我有一个这样的产品阵列。
$rows = [
100 => [
['product_id' => 101, 'name' => ''],
['product_id' => 102, 'name' => ''],
['product_id' => 103, 'name' => ''],
],
200 => [
['product_id' => 201, 'name' => ''],
['product_id' => 202, 'name' => ''],
],
300 => [
['product_id' => 301, 'name' => ''],
['product_id' => 302, 'name' => ''],
['product_id' => 303, 'name' => ''],
['product_id' => 304, 'name' => ''],
]
];
我想把它转置到这个结构中去掉一层深度。
$rows = [
['product_id' => 101, 'name' => ''], //1st from 100 subArray
['product_id' => 201, 'name' => ''], //1st from 200 subArray
['product_id' => 301, 'name' => ''], //1st from 300 subArray
['product_id' => 102, 'name' => ''], //2nd from 100 subArray
['product_id' => 202, 'name' => ''], //etc...
['product_id' => 302, 'name' => ''],
['product_id' => 103, 'name' => ''],
['product_id' => 303, 'name' => ''],
['product_id' => 304, 'name' => ''],
];
现在我正试图用这段代码来做这件事:
$max_store_products = max(array_map('count', $rows));
$sortedArray = array();
for($j = 0; $j < $max_store_products; $j++)
{
foreach($rows as $store_id => $store_products)
{
$sp = $rows[$store_id][$j];
if(isset($sp))
{
$sortedArray[] = $rows[$store_id][$j];
}
else
unset($rows[$store_id]);
}
}
但这需要很长的时间 而且也没有得到我想要的结果
有什么更简单的方法吗?
我们拿一个简单的数组来解释。
Array(
0 => Array(1, 4, 7),
1 => Array(2, 5, 8),
2 => Array(3, 6, 9),
)
首先我们 array_shift()
一个匿名函数到你的数组中,所以你的数组看起来像这样。
Array(
0 => function(){...}
//Your values
1 => Array(1, 4, 7),
2 => Array(2, 5, 8),
3 => Array(3, 6, 9),
)
然后我们调用 call_user_func_array()
并应用 array_map()
作为回调。这基本上是要做什么。
//↓ 'array_map()' callback from 'call_user_func_array()'
array_map(function(){
//Callback from the First array element
// Second Third Fourth
// array element array element array element more elements...
// ↓ ↓ ↓ ↓
}, Array(1, 4, 7), Array(2, 5, 8), Array(3, 6, 9) /* , ... */);
Array(1, 4, 7), Array(2, 5, 8), Array(3, 6, 9) /* , ... */
│ │ │ │ │ │ │ │ └─ 3 iteration in 'array_map()' | 3 value
│ │ │ │ │ │ │ └──── 2 iteration in 'array_map()' | 3 value
│ │ │ │ │ │ └─────── 1 iteration in 'array_map()' | 3 value
│ │ │ │ │ │
│ │ │ │ │ └───────────────── 3 iteration in 'array_map()' | 2 value
│ │ │ │ └──────────────────── 2 iteration in 'array_map()' | 2 value
│ │ │ └─────────────────────── 1 iteration in 'array_map()' | 2 value
│ │ │
│ │ └───────────────────────────────── 3 iteration in 'array_map()' | 1 value
│ └──────────────────────────────────── 2 iteration in 'array_map()' | 1 value
└─────────────────────────────────────── 1 iteration in 'array_map()' | 1 value
现在这意味着我们将一次循环浏览所有的子数组,一个一个的值 然后将匿名函数应用到我们循环浏览的所有值上。在匿名函数本身,我们基本上只是 array_merge()
将当前迭代中得到的值存入结果数组。
$result = array_merge($result, Array(1, 2, 3)); //First values from each subArray
$result = array_merge($result, Array(4, 5, 6)); //Second values from each subArray
$result = array_merge($result, Array(7, 8, 9)); //Third values from each subArray
//...
<?php
$arr = []; //Your array here
$result = [];
array_unshift($arr, function(...$values)use(&$result){
$result = array_merge($result, array_filter($values));
});
call_user_func_array("array_map", $arr);
print_r($result);
?>
这个解决方案并不依赖于数组值的唯一性和可排序性,它将通过总是从每个数组中抽取一个元素来合并你的所有数组。它将通过从每个数组中取出一个元素来合并所有的数组。
$result = array_filter(array_reduce(array_map(null, ...$rows), 'array_merge' ,[]));
var_dump($rows);
让我们来分析一下。
$columns = array_map(null, ...$rows);
当你通过 null
的第一论点 array_map
它的行为与:
$columns = array_map(function (...$vals) {
return $vals;
}, ...$rows);
这基本上是转置的 $rows
,所以你会得到一个数组,每个部分都有第一、第二、第三等元素。传递 null
而不是回调,可能看起来很奇怪,但实际上这并不是一个黑客,因为它的描述是在 文件.
$rawResult = array_reduce($columns, 'array_merge', []);
这里你只需将所有的列合并成一个数组。
$result = array_filter($rawResult);
array_filter
删除任何 NULL
条目,以防你的内部数组长度不均。
假设你的值有一些排序的东西,如 product_id
在你的例子中,你可以先合并数组,然后对结果进行排序。
$result = array_merge(...$rows);
usort($result, function ($a, $b) {
return $a['product_id'] % 100 - $b['product_id'] % 100 ?: $a['product_id'] - $b['product_id'];
});
var_dump($result); // merged & sorted result
我很确定这就是你想要的
<?php
$result = [];
// Get the highest number of items in an entry of `$rows`
$maxItems = 0;
foreach($rows as $row) {
if (count($row)>$maxItems) $maxItems = $row;
}
for($ii=0; $ii < $maxItems; $ii++) {
foreach($rows as $row) {
if (isset($row[$ii])) {
$result[] = $row[ii];
}
}
}
?>
你自己的版本之所以会失败 是因为你有这行字
if(isset($sp))
然而, $sp
总是定义在那里。PHP没有一个 undefined
类型,就像javascript一样,所以一旦你从一个数组中取出一个项目(不管它是否存在),它被定义了,就会抛出一个 E_NOTICE
并导致 null
. 你真的应该在PHP中增加错误信息,因为这很明显。
至于速度,你没有太多的办法来提高速度。你可以这样做。
无论如何,如果你首先考虑一下为什么要这样做,以及是否有更理智的方法来解决这个问题,而不只是解决你的循环,可能会更好。如果你真的因为要处理大量的数据而导致性能不好,那么需要修复的可能是应用设计,而不是这个循环。
使用。
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;
}