Стоит отметить, что если вы используете json_decode(file_get_contents("php://input"))
(как указывали другие), это не удастся, если строка not действительна JSON.
Это может быть просто разрешив сначала проверку правильности JSON. т.е.
function isValidJSON($str) {
json_decode($str);
return json_last_error() == JSON_ERROR_NONE;
}
$json_params = file_get_contents("php://input");
if (strlen($json_params) > 0 && isValidJSON($json_params))
$decoded_params = json_decode($json_params);
Изменить: обратите внимание, что удаление strlen($json_params)
выше может привести к тонким ошибкам, поскольку json_last_error()
изменяет не , когда null
или пустая строка передается , как показано здесь: http://ideone.com/va3u8U
Вот еще один способ. Промежуточные переменные не сохраняются.
Мы использовали это для удаления дубликатов результатов из множества перекрывающихся запросов.
$input = array_map("unserialize", array_unique(array_map("serialize", $input)));
Очень простой и логичный способ для уникального многомерного массива выглядит следующим образом:
Если у вас есть такой массив:
Array
(
[Key1] => Array
(
[0] => Value1
[1] => Value2
[2] => Value1
[3] => Value3
[4] => Value1
)
[Key2] => Array
(
[0] => Value1
[1] => Value2
[2] => Value1
[3] => Value3
[4] => Value4
)
)
используйте foreach
, чтобы решить эту проблему :
foreach($array as $k=>$v){
$unique=array_unique($v);
$array[$k]=$unique;
}
он даст вам следующий результат:
Array
(
[Key1] => Array
(
[0] => Value1
[1] => Value2
[3] => Value3
)
[Key2] => Array
(
[0] => Value1
[1] => Value2
[3] => Value3
[4] => Value4
)
)
, и если вы хотите изменить порядок клавиш,
foreach($array as $k=>$v){
$unique= array_values(array_unique($v));
$array[$k]=$unique;
}
Эта операция даст вам упорядоченные ключевые значения, такие как:
Array
(
[Key1] => Array
(
[0] => Value1
[1] => Value2
[2] => Value3
)
[Key2] => Array
(
[0] => Value1
[1] => Value2
[2] => Value3
[3] => Value4
)
)
Надеюсь, это очистит все.
Просто используйте параметр SORT_REGULAR в качестве второго параметра.
$uniqueArray = array_unique($array, SORT_REGULAR);
Поскольку люди говорят, что array_unique()
очень медленный, вот фрагмент, который я использую для многомерного массива одного уровня.
$serialized_array = array_map("serialize", $input);
foreach ($serialized_array as $key => $val) {
$result[$val] = true;
}
$output = array_map("unserialize", (array_keys($result)));
Ссылка, сделанная первым пользователем array_unique()
в php.net
$output = array_map('unserialize', array_keys($result));
– keyboardSmasher
16 May 2015 в 15:18
Если «удалить дубликаты» означает «удалить дубликаты, но пусть один там», решение может заключаться в том, чтобы сначала применить array_unique(...)
в «столбце идентификатора», а затем удалить в исходном массиве все ключи, которые имеют были удалены из массива столбцов:
$array = [
[
'id' => '123',
'foo' => 'aaa',
'bar' => 'bbb'
],
[
'id' => '123',
'foo' => 'ccc',
'bar' => 'ddd'
],
[
'id' => '567',
'foo' => 'eee',
'bar' => 'fff'
]
];
$ids = array_column($array, 'id');
$ids = array_unique($ids);
$array = array_filter($array, function ($key, $value) use ($ids) {
return in_array($value, array_keys($ids));
}, ARRAY_FILTER_USE_BOTH);
Результат:
Array
(
[0] => Array
(
[id] => 123
[foo] => aaa
[bar] => bbb
)
[2] => Array
(
[id] => 567
[foo] => eee
[bar] => fff
)
)
Альтернатива сериализации и уникальности
$test = [
['abc','def'],
['ghi','jkl'],
['mno','pql'],
['abc','def'],
['ghi','jkl'],
['mno','pql'],
];
$result = array_reduce(
$test,
function($carry,$item){
if(!in_array($item,$carry)) {
array_push($carry,$item);
}
return $carry;
},
[]
);
var_dump($result);
/*
php unique.php
array(3) {
[0] =>
array(2) {
[0] =>
string(3) "abc"
[1] =>
string(3) "def"
}
[1] =>
array(2) {
[0] =>
string(3) "ghi"
[1] =>
string(3) "jkl"
}
[2] =>
array(2) {
[0] =>
string(3) "mno"
[1] =>
string(3) "pql"
}
}
* /
Легко читаемое решение, возможно, не самое эффективное:
function arrayUnique($myArray){
if(!is_array($myArray))
return $myArray;
foreach ($myArray as &$myvalue){
$myvalue=serialize($myvalue);
}
$myArray=array_unique($myArray);
foreach ($myArray as &$myvalue){
$myvalue=unserialize($myvalue);
}
return $myArray;
}
Начиная с 5.2.9 вы можете использовать array_unique()
, если вы используете флаг SORT_REGULAR
следующим образом:
array_unique($array, SORT_REGULAR);
Это делает функцию сравнения элементов для равенства как если $a == $b
используются, что идеально подходит для вашего случая.
Выход
Array
(
[0] => Array
(
[0] => abc
[1] => def
)
[1] => Array
(
[0] => ghi
[1] => jkl
)
[2] => Array
(
[0] => mno
[1] => pql
)
)
Имейте в виду, что документация указывает :
blockquote>
array_unique()
не предназначен для работы с многомерными массивами.
, если у вас есть такой массив:
(пользователи - это имя массива)
Array=>
[0] => (array)
'user' => 'john'
'age' => '23'
[1] => (array)
'user' => 'jane'
'age' => '20'
[2]=> (array)
'user' => 'john'
'age' => '23'
, и вы хотите удалить дубликаты ... затем:
$serialized = array();
for ($i=0; $i < sizeof($users); $i++) {
$test = in_array($users['user'], $serialized);
if ($test == false) {
$serialized[] = $users['user'];
}
}
может быть решением: P
Многие люди спрашивали меня, как сделать уникальный многомерный массив. Я получил ссылку с вашего комментария, и мне это помогает.
Прежде всего, спасибо @jeromegamez @daveilers для вашего решения. Но каждый раз, когда я давал ответ, они спрашивали меня, как это «сериализовать» и «неэриализовать». Вот почему я хочу поделиться с вами причиной этого, чтобы он помог большему количеству людей понять концепцию, стоящую за этим.
Я объясняю, почему мы используем «serialize» и «unserialize» в шагах:
Шаг 1: Преобразование многомерного массива в одномерный массив
To преобразовать многомерный массив в одномерный массив, сначала сгенерировать представление потока байтов всех элементов (включая вложенные массивы) внутри массива. Функция serialize () может генерировать представление байтового потока значения. Чтобы генерировать представление байтов по всем элементам, вызовите функцию serialize () внутри функции array_map () как функцию обратного вызова. Результат будет одномерным массивом независимо от того, сколько уровней имеет многомерный массив.
Шаг 2: Сделайте уникальные значения
Чтобы сделать этот одномерный массив уникальным, используйте array_unique ( ).
Шаг 3: Верните его в многомерный массив
. Хотя массив теперь уникален, значения выглядят как представление потока байтов. Чтобы вернуть его обратно в многомерный массив, используйте функцию unserialize ().
$input = array_map("unserialize", array_unique(array_map("serialize", $input)));
Еще раз спасибо за все это.
Пользовательские комментарии к документации array_unique () имеют много решений. Вот один из них:
kenrbnsn at rbnsn dot com 27-Sep-2005 12:09
Еще один массив Array_Unique для многоразмерных массивов. Я тестировал это только на двухэтапных массивах, но его можно было бы обобщить для большего или использовать рекурсию.
Эта функция использует функции serialize, array_unique и unserialize для выполнения этой работы.
blockquote>function multi_unique($array) { foreach ($array as $k=>$na) $new[$k] = serialize($na); $uniq = array_unique($new); foreach($uniq as $k=>$ser) $new1[$k] = unserialize($ser); return ($new1); }
Это из http://ca3.php.net/manual/en/function.array-unique.php#57202 .
У меня была аналогичная проблема, но я нашел для нее 100% -ное решение.
<?php
function super_unique($array,$key)
{
$temp_array = [];
foreach ($array as &$v) {
if (!isset($temp_array[$v[$key]]))
$temp_array[$v[$key]] =& $v;
}
$array = array_values($temp_array);
return $array;
}
$arr="";
$arr[0]['id']=0;
$arr[0]['titel']="ABC";
$arr[1]['id']=1;
$arr[1]['titel']="DEF";
$arr[2]['id']=2;
$arr[2]['titel']="ABC";
$arr[3]['id']=3;
$arr[3]['titel']="XYZ";
echo "<pre>";
print_r($arr);
echo "unique*********************<br/>";
print_r(super_unique($arr,'titel'));
?>
Array
(
[0] => Array
(
[id] => 1
[name] => john
)
[1] => Array
(
[id] => 2
[name] => smith
)
[2] => Array
(
[id] => 3
[name] => john
)
[3] => Array
(
[id] => 4
[name] => robert
)
)
$temp = array_unique(array_column($array, 'name'));
$unique_arr = array_intersect_key($array, $temp);
Это приведет к удалению дубликатов имен из массива. уникальный ключ
Если у вас есть такой массив
data = array
(
[0] => array
(
[subject] => a
[object] => c
),
[1] => array
(
[subject] => b
[object] => d
),
[2] => array
(
[subject] => d
[object] => b
),
[3] => array
(
[subject] => d
[object] => c
),
[4] => array
(
[subject] => c
[object] => a
),
[5] => array
(
[subject] => c
[object] => d
)
)
, и вы хотите получить такие массивы:
data = array
(
[0] => array
(
[subject] => a
[object] => c
),
[1] => array
(
[subject] => b
[object] => d
),
[2] => array
(
[subject] => d
[object] => c
)
)
или
data = array
(
[0] => array
(
[subject] => d
[object] => b
),
[1] => array
(
[subject] => c
[object] => a
),
[2] => array
(
[subject] => c
[object] => d
)
)
следующий код может помочь
$data1 = array();
$data1 = $data;
for($q=0;$q<count($data);$q++)
{
for($p=0;$p<count($data1);$p++)
{
if (($data[$q]["subject"] == $data1[$p]["object"]) && ($data[$q]["object"] == $data1[$p]["subject"]))
{
$data1[$p]["subject"] = $data[$q]["subject"];
$data1[$p]["object"] = $data[$q]["object"];
}
}
}
$data1 = array_values(array_map("unserialize", array_unique(array_map("serialize", $data1))));
$data = $data1;
Я много думал об этой проблеме и решил, что оптимальное решение должно следовать двум правилам.
Учитывая это и учитывая все причуды PHP, ниже приведено решение I придумал. В отличие от некоторых других ответов, он имеет возможность удалять элементы на основе любого ключа (ов), который вы хотите. Ожидается, что входной массив будет числовым.
$count_array = count($input);
for ($i = 0; $i < $count_array; $i++) {
if (isset($input[$i])) {
for ($j = $i+1; $j < $count_array; $j++) {
if (isset($input[$j])) {
//this is where you do your comparison for dupes
if ($input[$i]['checksum'] == $input[$j]['checksum']) {
unset($input[$j]);
}
}
}
}
}
Единственным недостатком является то, что клавиши не в порядке, когда итерация завершается. Это не проблема, если впоследствии вы используете только петли foreach, но если вам нужно использовать цикл for, вы можете поместить $input = array_values($input);
после этого, чтобы перенумеровать ключи.
, если вам нужно устранить дубликаты для определенных ключей, таких как id mysqli, вот простой funciton
function search_array_compact($data,$key){
$compact = [];
foreach($data as $row){
if(!in_array($row[$key],$compact)){
$compact[] = $row;
}
}
return $compact;
}
Бонусные баллы. Вы можете передать массив ключей и добавить внешний foreach, но это будет 2 раза медленнее за дополнительный ключ.
serialize(array('a' => '1', 'b' => '1'))
отличается отserialize(array('b' => '1', 'a' => '1'))
. Эта опция не будет использоваться для массивов, используемых какsets
или(hash)maps
. – Andras Gyomrey 19 October 2016 в 14:49