Получить ключи для повторяющихся значений в массиве - PullRequest
10 голосов
/ 24 июня 2011

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

$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]

Ответы [ 9 ]

20 голосов
/ 24 июня 2011
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 будет содержать многомерный массив с ключом дублированного значения, содержащий каждый ключ, который был дубликатом, и, если вы отправите "true""в качестве второго аргумента он вернет исходный массив без повторяющихся значений.

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

13 голосов
/ 24 июня 2011

Сначала я отвечу на второй вопрос. Вы хотите использовать 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
)
1 голос
/ 28 декабря 2015
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;
}
1 голос
/ 13 июня 2013

У меня была та же проблема, что и у вопроса №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
)
1 голос
/ 24 июня 2011

вот код чувак

   $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 теперь массив, содержащий ключи дублированных массивов;) пока

1 голос
/ 24 июня 2011
$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)
}
0 голосов
/ 11 мая 2019

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

$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 ) 
0 голосов
/ 24 июня 2011

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

$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']); возвращает ключи.

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

0 голосов
/ 24 июня 2011
$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];
}

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

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

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

Вот dump 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
)
...