Получить ключи для повторяющихся значений в массиве

У меня есть следующий массив:

$myarray = Array("2011-06-21", "2011-06-22", "2011-06-22", "2011-06-23", "2011-06-23", "2011-06-24", "2011-06-24", "2011-06-25", "2011-06-25", "2011-06-26");
var_dump($myarray);

Результат:

Array (
    [0] => 2011-06-21
    [1] => 2011-06-22
    [2] => 2011-06-22
    [3] => 2011-06-23
    [4] => 2011-06-23
    [5] => 2011-06-24
    [6] => 2011-06-24
    [7] => 2011-06-25
    [8] => 2011-06-25
    [9] => 2011-06-26
)
  1. Теперь, как я могу отобразить ключи с повторяющимися значениями? Здесь функция НЕ должна возвращать ([0], [9]), так как нет дубликатов со значениями.
  2. Как найти ключи для того же значения, например. для "2011-06-25" должно возвращаться [7], [8]

Ответ 1

function get_keys_for_duplicate_values($my_arr, $clean = false) {
    if ($clean) {
        return array_unique($my_arr);
    }

    $dups = $new_arr = array();
    foreach ($my_arr as $key => $val) {
      if (!isset($new_arr[$val])) {
         $new_arr[$val] = $key;
      } else {
        if (isset($dups[$val])) {
           $dups[$val][] = $key;
        } else {
           $dups[$val] = array($key);
           // Comment out the previous line, and uncomment the following line to
           // include the initial key in the dups array.
           // $dups[$val] = array($new_arr[$val], $key);
        }
      }
    }
    return $dups;
}

очевидно, имя функции немного длиннее;)

Теперь $dups будет содержать многомерный массив с двойным значением, содержащий каждый ключ, который является дубликатом, и если вы отправляете "истинный" в качестве второго аргумента, он возвращает исходный массив без повторяющихся значений.

В качестве альтернативы вы можете передать исходный массив в качестве ссылки, и он соответствующим образом отрегулирует его, возвращая ваш дублированный массив

Ответ 2

Сначала отвечу на второй вопрос. Вы хотите использовать array_keys с указанным значением "search_value".

$keys = array_keys($array, "2011-06-29")

В приведенном ниже примере $duplicates будет содержать значения дублирования, а $result будет содержать те, которые не дублируются. Чтобы получить ключи, просто используйте array_keys.

<?php

$array = array(
  'a',
  'a',
  'b',
  'c',
  'd'
);

// Unique values
$unique = array_unique($array);

// Duplicates
$duplicates = array_diff_assoc($array, $unique);

// Unique values
$result = array_diff($unique, $duplicates);

// Get the unique keys
$unique_keys = array_keys($result);

// Get duplicate keys
$duplicate_keys = array_keys(array_intersect($array, $duplicates));

Результат:

// $duplicates
Array
(
    [1] => a
)

// $result
Array
(
    [2] => b
    [3] => c
    [4] => d
)

// $unique_keys
Array
(
    [0] => 2
    [1] => 3
    [2] => 4
)

// $duplicate_keys
Array
(
    [0] => 0
    [1] => 1
)

Ответ 3

$array = array(0 => "1", 1 => "1", 2 => "2", 3 => "3");
$count = array();
foreach($array as $key => $value) {
  if(!isset($count[$value])) {
    $count[$value] = 0;
  }
  $count[$value]++;
}


$result = array_filter($count, function($value) {
  return $value > 1;
});

$result = array_keys($result);

var_dump($result);

Выход

array(1) {
  [0]=>
  int(1)
}

Ответ 4

вот код чувак

   $your_array = array(0 => '2011-06-21', 1 => '2011-06-22', 2 => '2011-06-22', 3 => '2011-06-23', 4 =>
'2011-06-23', 5 => '2011-06-24', 6 => '2011-06-24', 7 => '2011-06-25', 8 => '2011-06-25', 9 
=> '2011-06-26', 10 => '2011-06-26', 11 => '2011-06-27', 12 => '2011-06-27', 13 => '2011-06-  
28', 14 => '2011-06-29', 15 => '2011-06-29', 16 => '2011-06-30', 17 => '2011-06-30', 18 => 
'2011-07-01', 19 => '2011-07-01', 20 => '2011-07-02', 21 => '2011-07-02', 22 => '2011-07-03', 
23 => '2011-07-03', 24 => '2011-07-04', 25 => '2011-07-04', 26 => '2011-07-05', 27 => '2011-
07-05', 28 => '2011-07-06', 29 => '2011-07-06', 30 => '2011-07-07', 31 => '2011-07-07');

$keys_of_duplicated = array();
$array_keys = array();

foreach($your_array as $key => $value) {
    //- get the keys of the actual value
    $array_keys = array_keys($your_array, $value);

    //- if there is more then one key collected we register it
    if(count($array_keys) > 1) {
        //- foreach key that have the same value we check if i'ts already registered
        foreach($array_keys as $key_registered) {
            //- if not registered we register it
            if(!in_array($key_registered,  $keys_of_duplicated)) {
                 $keys_of_duplicated[] = $key_registered;
            }
        }
    }
}

var_dump($keys_of_duplicated);

$keys_of_duplicated - теперь массив, содержащий ключи дублированных массивов;) bye

Ответ 5

У меня была аналогичная проблема с вопросом № 1 из ОП. Все, что мне было нужно, это ключи для повторяющихся значений в моем исходном массиве. Вот что я придумал:

$array = array('yellow', 'red', 'green', 'brown', 'red', 'brown');

$counts = array_count_values($array);
$filtered = array_filter($counts, function($value) {
    return $value != 1;
});
$result = array_keys(array_intersect($array, array_keys($filtered)));

И для вывода:

print_r($result);
Array
(
    [0] => 1
    [1] => 3
    [2] => 4
    [3] => 5
)

Ответ 6

function getDuplicateValueKeys($my_arr, $clean = false) 
{
    if ($clean) {
        return array_unique($my_arr);
    }
    $dups = array();
    $new_arr = array();
    $dup_vals = array();

    foreach ($my_arr as $key => $value) {
        if (!isset($new_arr[$value])) {
            $new_arr[$value] = $key;
        } else {
            array_push($dup_vals,$value);
        }
    }

    foreach ($my_arr as $key => $value) {
        if (in_array($value, $dup_vals)) {
            if (!isset($dups[$value])) {
                $dups[$value]=array($key);
            }else{
                array_push($dups[$value],$key);
            }
        }
    }

    return $dups;
}

Ответ 7

$array = array(
    '2011-06-21','2011-06-22','2011-06-22','2011-06-23',
    '2011-06-23','2011-06-24','2011-06-24','2011-06-25',
    '2011-06-25','2011-06-26','2011-06-26','2011-06-27',
    '2011-06-27','2011-06-28','2011-06-29','2011-06-29',
    '2011-06-30','2011-06-30','2011-07-01','2011-07-01',
    '2011-07-02','2011-07-02','2011-07-03','2011-07-03',
    '2011-07-04','2011-07-04','2011-07-05','2011-07-05',
    '2011-07-06','2011-07-06','2011-07-07','2011-07-07',
);

function getDupKeys(array $array, $return_first = true, $return_by_key = true) {
    $seen = array();
    $dups = array();

    foreach ($array as $k => $v) {
        $vk = $return_by_key ? $v : 0;
        if (!array_key_exists($v, $seen)) {
            $seen[$v] = $k;
            continue;
        }
        if ($return_first && !array_key_exists($v, $dups)) {
            $dups[$vk][] = $seen[$v];
        }
        $dups[$vk][] = $k;
    }
    return $return_by_key ? $dups : $dups[0];
}

Если оба необязательных параметра верны, он возвращает массив массивов; ключ каждого дочернего массива будет значением, которое не было уникальным, а значениями массива будут все те ключи, которые имели это значение.

Если первый необязательный параметр является ложным, то будут возвращены только ключи после первого экземпляра не уникального значения (т.е. для данного массива каждое значение возвращает только один ключ, второй раз, когда он произошел, вместо первый).

Если второй параметр не является обязательным, вместо того, чтобы возвращать массив массивов, он возвращает плоский массив, содержащий все повторяющиеся ключи (точно, какие ключи он возвращает, продиктован предыдущим необязательным параметром).

Здесь дамп print_r, он становится более красивым:

print_r(getDupKeys($array));

Array
(
    [2011-06-22] => Array
        (
            [0] => 1
            [1] => 2
        )

    [2011-06-23] => Array
        (
            [0] => 3
            [1] => 4
        )

    [2011-06-24] => Array
        (
            [0] => 5
            [1] => 6
        )

    [2011-06-25] => Array
        (
            [0] => 7
            [1] => 8
        )

    [2011-06-26] => Array
        (
            [0] => 9
            [1] => 10
        )

    [2011-06-27] => Array
        (
            [0] => 11
            [1] => 12
        )

    [2011-06-29] => Array
        (
            [0] => 14
            [1] => 15
        )

    [2011-06-30] => Array
        (
            [0] => 16
            [1] => 17
        )

    [2011-07-01] => Array
        (
            [0] => 18
            [1] => 19
        )

    [2011-07-02] => Array
        (
            [0] => 20
            [1] => 21
        )

    [2011-07-03] => Array
        (
            [0] => 22
            [1] => 23
        )

    [2011-07-04] => Array
        (
            [0] => 24
            [1] => 25
        )

    [2011-07-05] => Array
        (
            [0] => 26
            [1] => 27
        )

    [2011-07-06] => Array
        (
            [0] => 28
            [1] => 29
        )

    [2011-07-07] => Array
        (
            [0] => 30
            [1] => 31
        )

)

print_r(getDupKeys($array, false));

Array
(
    [2011-06-22] => Array
        (
            [0] => 2
        )

    [2011-06-23] => Array
        (
            [0] => 4
        )

    [2011-06-24] => Array
        (
            [0] => 6
        )

    [2011-06-25] => Array
        (
            [0] => 8
        )

    [2011-06-26] => Array
        (
            [0] => 10
        )

    [2011-06-27] => Array
        (
            [0] => 12
        )

    [2011-06-29] => Array
        (
            [0] => 15
        )

    [2011-06-30] => Array
        (
            [0] => 17
        )

    [2011-07-01] => Array
        (
            [0] => 19
        )

    [2011-07-02] => Array
        (
            [0] => 21
        )

    [2011-07-03] => Array
        (
            [0] => 23
        )

    [2011-07-04] => Array
        (
            [0] => 25
        )

    [2011-07-05] => Array
        (
            [0] => 27
        )

    [2011-07-06] => Array
        (
            [0] => 29
        )

    [2011-07-07] => Array
        (
            [0] => 31
        )

)

print_r(getDupKeys($array, true, false));

Array
(
    [0] => 1
    [1] => 2
    [2] => 3
    [3] => 4
    [4] => 5
    [5] => 6
    [6] => 7
    [7] => 8
    [8] => 9
    [9] => 10
    [10] => 11
    [11] => 12
    [12] => 14
    [13] => 15
    [14] => 16
    [15] => 17
    [16] => 18
    [17] => 19
    [18] => 20
    [19] => 21
    [20] => 22
    [21] => 23
    [22] => 24
    [23] => 25
    [24] => 26
    [25] => 27
    [26] => 28
    [27] => 29
    [28] => 30
    [29] => 31
)

print_r(getDupKeys($array, false, false));

Array
(
    [0] => 2
    [1] => 4
    [2] => 6
    [3] => 8
    [4] => 10
    [5] => 12
    [6] => 15
    [7] => 17
    [8] => 19
    [9] => 21
    [10] => 23
    [11] => 25
    [12] => 27
    [13] => 29
    [14] => 31
)

Ответ 8

Мне очень нравится, что Франсуа отвечает, вот что я придумал, чтобы сохранить ключи. Сначала я отвечу на первый вопрос:

$array = array('2011-06-21', '2011-06-22', '2011-06-22');
/**
 * flip an array like array_flip but
 * preserving multiple keys per an array value
 * 
 * @param array $a
 * @return array
 */
function array_flip_multiple(array $a) {
    $result = array();
    foreach($a as $k=>$v)
        $result[$v][]=$k
        ;
    return $result;
}

$hash = array_flip_multiple($array);

// filter $hash based on your specs (2 or more)
$hash = array_filter($hash, function($items) {return count($items) > 1;});

// get all remaining keys
$keys = array_reduce($hash, 'array_merge', array());

var_dump($array, $hash, $keys);

:

# original array
array(3) {
  [0]=>
  string(10) "2011-06-21"
  [1]=>
  string(10) "2011-06-22"
  [2]=>
  string(10) "2011-06-22"
}

# hash (filtered)
array(1) {
  ["2011-06-22"]=>
  array(2) {
    [0]=>
    int(1)
    [1]=>
    int(2)
  }
}

# the keys
array(2) {
  [0]=>
  int(1)
  [1]=>
  int(2)
}

Итак, теперь второй вопрос:

Просто используйте $hash, чтобы получить ключи для значения:

var_dump($hash['2011-06-22']); возвращает ключи.

Преимущество: если вам нужно проверить несколько значений, данные уже хранятся в хеше и доступны для использования.

Ответ 9

Другой пример:

$array = array(
  'a',
  'a',
  'b',
  'b',
  'b'
);
echo '<br/>Array: ';
print_r($array);
// Unique values
$unique = array_unique($array);
echo '<br/>Unique Values: ';
print_r($unique);
// Duplicates
$duplicates = array_diff_assoc($array, $unique);
echo '<br/>Duplicates: ';
print_r($duplicates);
// Get duplicate keys
$duplicate_values = array_values(array_intersect($array, $duplicates));
echo '<br/>duplicate values: ';
print_r($duplicate_values);

Выход:

Array :Array ( [0] => a [1] => a [2] => b [3] => b [4] => b ) 
Unique Values :Array ( [0] => a [2] => b ) 
Duplicates :Array ( [1] => a [3] => b [4] => b ) 
Duplicate Values :Array ( [0] => a [1] => a [2] => b [3] => b [4] => b )