Php 将三维数组合并为单个数组并删除重复值?
我得到的三维数组在不同的数组中有重复的值,我想将这个三维数组合并成一个数组,并删除最终数组中的重复值Php 将三维数组合并为单个数组并删除重复值?,php,arrays,sorting,multidimensional-array,Php,Arrays,Sorting,Multidimensional Array,我得到的三维数组在不同的数组中有重复的值,我想将这个三维数组合并成一个数组,并删除最终数组中的重复值 function flatten (array $xs) { return array_reduce ( $xs , 'array_merge' , [] ) ; } var_export (flatten ($data)); // array ( // 0 => // array ( 'role_id' => 2, 'nam
function flatten (array $xs) {
return array_reduce
( $xs
, 'array_merge'
, []
)
;
}
var_export (flatten ($data));
// array (
// 0 =>
// array ( 'role_id' => 2, 'name' => 'name1', 'email' => 'email1@somemail.com', ),
// 1 =>
// array ( 'role_id' => 2, 'name' => 'name2', 'email' => 'email2@somemail.com', ),
// 2 =>
// array ( 'role_id' => 2, 'name' => 'name3', 'email' => 'email3@somemail.com', ),
// 3 =>
// array ( 'role_id' => 2, 'name' => 'name4', 'email' => 'email4@somemail.com', ),
// 4 =>
// array ( 'role_id' => 2, 'name' => 'name3', 'email' => 'email3@somemail.com', ),
// 5 =>
// array ( 'role_id' => 2, 'name' => 'name3', 'email' => 'email3@somemail.com', ),
// 6 =>
// array ( 'role_id' => 2, 'name' => 'name2', 'email' => 'email2@somemail.com', ),
// 7 =>
// array ( 'role_id' => 2, 'name' => 'name3', 'email' => 'email3@somemail.com', ),
// )
我的阵列是:
Array
(
[0] => Array
(
[0] => Array
(
[role_id] => 2
[name] => name1
[email] => email1@somemail.com
)
[1] => Array
(
[role_id] => 2
[name] => name2
[email] => email2@somemail.com
)
[2] => Array
(
[role_id] => 2
[name] => name3
[email] => email3@somemail.com
)
)
[1] => Array
(
[0] => Array
(
[role_id] => 2
[name] => name4
[email] => email4@somemail.com
)
[1] => Array
(
[role_id] => 2
[name] => name3
[email] => email3@somemail.com
)
)
[2] => Array
(
[0] => Array
(
[role_id] => 2
[name] => name3
[email] => email3@somemail.com
)
[1] => Array
(
[role_id] => 2
[name] => name2
[email] => email2@somemail.com
)
)
[3] => Array
(
[0] => Array
(
[role_id] => 2
[name] => name3
[email] => email3@somemail.com
)
)
)
我尝试了以下解决方案,但没有成功:
Solution-1: array_unique(array_merge($array1,$array2), SORT_REGULAR);
Solution-2: function array_flatten($array) {
if (!is_array($array)) {
return FALSE;
}
$result = array();
foreach ($array as $key => $value) {
if (is_array($value)) {
$result = array_merge($result, array_flatten($value));
}
else {
$result[$key] = $value;
}
}
return $result;
}
Solution-3: $input = array_map("unserialize", array_unique(array_map("serialize", $input)));
我想将这个数组合并成一个一维数组,并从中删除重复的值。我可以通过每个数组循环得到结果,但执行时间会更长,我希望一定有一些简单的解决方案。任何人都可以解决此问题,谢谢。请尝试此代码
$list = is your array;
$flattern_array = array();
$flat_array = function($item) use(&$flattern_array, &$flat_array){
$keys = array_keys($item);
if(is_array($item) && !in_array("role_id", $keys, TRUE)){
foreach($item as $_item){
$flat_array($_item);
}
}else{
$flattern_array[] = $item;
}
};
$flat_array($list);
// Now $flattern_array have all items
//Here we can remove duplicates from array
$result = array_map("unserialize", array_unique(array_map("serialize", $flattern_array)));
我们将从创建一些通用函数开始,而不是为这个数据集编写一个纯粹的定制解决方案,这些函数可以使处理一般数据变得更容易 我们从一个
flatten
函数开始,该函数接受一个N
维数组并返回一个N-1
维数组
function flatten (array $xs) {
return array_reduce
( $xs
, 'array_merge'
, []
)
;
}
var_export (flatten ($data));
// array (
// 0 =>
// array ( 'role_id' => 2, 'name' => 'name1', 'email' => 'email1@somemail.com', ),
// 1 =>
// array ( 'role_id' => 2, 'name' => 'name2', 'email' => 'email2@somemail.com', ),
// 2 =>
// array ( 'role_id' => 2, 'name' => 'name3', 'email' => 'email3@somemail.com', ),
// 3 =>
// array ( 'role_id' => 2, 'name' => 'name4', 'email' => 'email4@somemail.com', ),
// 4 =>
// array ( 'role_id' => 2, 'name' => 'name3', 'email' => 'email3@somemail.com', ),
// 5 =>
// array ( 'role_id' => 2, 'name' => 'name3', 'email' => 'email3@somemail.com', ),
// 6 =>
// array ( 'role_id' => 2, 'name' => 'name2', 'email' => 'email2@somemail.com', ),
// 7 =>
// array ( 'role_id' => 2, 'name' => 'name3', 'email' => 'email3@somemail.com', ),
// )
现在,如果我们可以使用PHP,那就太好了,但它只适用于原始值。在这种情况下,我们需要一个函数,它允许我们指定更复杂的匹配行为。为此,我们通过函数使我们自己的数组成为唯一的
function array_unique_by (array $xs, callable $f) {
return array_reduce
( $xs
, function ($acc, $x) use ($f) {
if ( array_search_by ( $acc
, function ($y) use ($f, $x) {
return call_user_func ($f, $x, $y);
}
)
=== null
)
return array_merge ($acc, [ $x ]);
else
return $acc;
}
, []
)
;
}
在继续之前,请注意,我们引入了数组搜索方法。与PHP的array\u unique
一样,PHP也只适用于原始值,因此我们需要一种搜索复杂值的方法,如数据集中的值
function array_search_by (array $xs, callable $f) {
foreach ($xs as $x) {
if (call_user_func($f, $x) === true)
return $x;
}
return null;
}
最后,为了使用array\u unique\u by
函数,我们需要向它传递一个匹配函数。此函数将通过
我们的数据集的哪些元素被视为“匹配”来告诉数组\u unique\u。作为一个例子,我们将其称为match\u user
,因为它看起来数据集中的元素都是用户
function match_user ($a, $b) {
return $a["role_id"] === $b["role_id"]
&& $a["name"] === $b["name"]
&& $a["email"] === $b["email"]
;
}
一切就绪后,我们现在可以编写一个非常简单的程序来实现您想要的结果
var_export (array_unique_by (flatten ($data), 'match_user'));
// array (
// 0 =>
// array ( 'role_id' => 2, 'name' => 'name1', 'email' => 'email1@somemail.com', ),
// 1 =>
// array ( 'role_id' => 2, 'name' => 'name2', 'email' => 'email2@somemail.com', ),
// 2 =>
// array ( 'role_id' => 2, 'name' => 'name3', 'email' => 'email3@somemail.com', ),
// 3 =>
// array ( 'role_id' => 2, 'name' => 'name4', 'email' => 'email4@somemail.com', ),
// )
备注
上面的函数是用函数式编写的,用PHP很难表达。我很难找到一个合适的语法格式为数组\u unique\u by
。关键是,您可以根据需要实现这些通用函数。下面是另一个可能的array\u unique\u实现,它是使用PHP程序员更熟悉的命令式样式实现的。此实现的行为与上面定义的版本完全相同,但可能会更好地向读者传达其意图
function array_unique_by (array $xs, callable $f) {
$acc = [];
foreach ($xs as $x) {
$match =
array_search_by
( $acc
, function ($y) use ($f, $x) {
return call_user_func ($f, $x, $y);
}
)
;
if ($match === null)
array_push ($acc, $x);
}
return $acc;
}
最后,PHP的lambda语法也相当笨拙。为了使用lambda之外定义的变量,我们必须使用这种笨拙的use($f,$x)
语法。我们可以用其他通用助手函数来解决这个问题,如下面介绍的partial
function partial (callable $f, ...$xs) {
return function (...$ys) use ($f, $xs) {
return call_user_func_array
( $f
, array_merge ($xs, $ys)
)
;
};
}
function array_unique_by (array $xs, callable $f) {
$acc = [];
foreach ($xs as $x) {
$match =
array_search_by
( $acc
, partial ($f, $x)
)
;
if ($match === null)
array_push ($acc, $x);
}
return $acc;
}
如上所述,array\u unique\u by
的工作原理与其他实现完全相同,但更易于阅读。你可以一直使用它,直到你满意为止
这里的想法很简单:您可以使用通用函数创建缺少的功能或抽象掉烦恼。然后,这些功能可以以各种优雅的方式组合在一起,从而生成一个更易于读者理解的程序
性能
我们的array\u unique\u by
功能利用了我们自己的array\u search\u by
功能。如果我们在心里想象正在进行的过程,我们输入中的每个元素都需要与我们正在构建的输出进行比较,$acc
。在这里,“查找匹配项”是通过在$acc
开头搜索,然后逐个查看每个元素,直到找到潜在匹配项
如果我们的输入数据非常大,这将导致非常糟糕的性能状况。优化这一点的一种方法是将$acc
构建为一个。但这当然意味着我们必须创建一个适合我们的数据集。或者我们可以利用PHP的接口来减少工作量。这种实现得益于二进制搜索,它比线性搜索快得多
这个练习留给读者。听起来不错。那么你尝试了什么?更新了我的问题,请检查。你说的单数组是什么意思?无法使此数据适合平面阵列。您必须至少有一级深度数组。另外,如果您使用var_导出而不是print_r/var_dump,也会很好,因为var_导出可以复制粘贴到代码中。