我需要在 woocommerce 中的产品属性的数据结构中进行排序,对每个属性及其值进行分组。
我现在的阵列
array (size=5)
0 =>
array (size=1)
'pa_color' =>
array (size=1)
0 => string 'red' (length=3)
1 =>
array (size=1)
'pa_color' =>
array (size=1)
0 => string 'red' (length=3)
2 =>
array (size=2)
'pa_color' =>
array (size=1)
0 => string 'gray' (length=4)
'pa_modello' =>
array (size=1)
0 => string 'modello2' (length=8)
3 =>
array (size=1)
'pa_color' =>
array (size=1)
0 => string 'yellow' (length=6)
4 =>
array (size=0)
empty
我需要合并类似的内容:
array (size=1)
'pa_color' =>
array (size=1)
0 => string 'red' (length=3)
1 => string 'gray' (length=4)
2 => string 'yellow' (length=6)
'pa_modello' =>
array (size=1)
0 => string 'modello2' (length=8)
将相同键的值分组到一个数组中。
提前致谢
global $wp_query;
$obj = get_queried_object();
foreach ($wp_query->posts as $_post) {
$_product = wc_get_product($_post->ID);
$wc_attr_objs = $_product->get_attributes();
$prod_attrs = [];
foreach ($wc_attr_objs as $wc_attr => $wc_term_objs) {
$prod_attrs[$wc_attr] = [];
$wc_terms = $wc_term_objs->get_terms();
foreach ($wc_terms as $wc_term) {
array_push($prod_attrs[$wc_attr], $wc_term->slug);
var_dump($prod_attrs);
}
}
$totals[] = $prod_attrs;
}
让
$array
是你的数组:
foreach ($array as $item)
{
if ($item['pa_color']['0']) $color[ $item['pa_color']['0'] ] = $item['pa_color']['0'];
if ($item['pa_modello']['0']) $modello[$item['pa_modello']['0']] = $item['pa_modello']['0'];
// this loop will remove the duplicated values and I Assume each pa_color , pa_modello in the original array contains only one element with 0 as a key
}
foreach ($color as $c) $newArray['pa_color'][] = $c;
foreach ($modello as $m) $newArray['pa_modello'][] = $m;
这应该可以完成工作。
编辑:
对于动态属性注释:
foreach ($array as $item)
foreach (array_keys($item) as $key) // getting the keys ex: pa_color
{
if ($item[$key]['0']) {
$temparray[$key][ $item[$key]['0'] ] = $item[$key]['0'];
}
// this loop will remove the duplicated values and I Assume each key in the original array contains only one element with 0 as a key
// the temparray will contain in its keys ($key) the pa_color , pa_module.. etc
// each of them will be an array with the key=value approach .. in case having two "red" it will not duplicate
}
// finally making it zero based array
foreach ($temparray as $key=>$item) // ex: $temparray['pa_color']['red'] = 'red'
foreach ($item as $value) // ex: $item['red'] = 'red'
$newArray[$key][] = $value; // ex: $newArray['pa_color'][0] = 'red';
看起来很复杂..我找不到更好的方法。
循环第一级条目,然后添加一个嵌套循环以根据子数组中的所需键和值创建变量。
因为最深的子数组中只有一个元素,所以您可以在嵌套循环内使用“数组解构”将单个元素值分配为
$value
。
通过将
$value
声明为结果数组中深度值的键,确保输出中的值唯一。
如果您确实希望对子数组重新索引,则可以使用
array_map()
和 array_values()
来实现这一点 - 但仅在必要时才执行此操作。
代码:(演示)
$result = [];
foreach ($array as $entries) {
foreach ($entries as $key => [$value]) {
$result[$key][$value] = $value;
}
}
var_export($result);
输出:
array (
'pa_color' =>
array (
'red' => 'red',
'gray' => 'gray',
'yellow' => 'yellow',
),
'pa_modello' =>
array (
'modello2' => 'modello2',
),
)
附注如果您的深层子数组可能有多个元素,那么只需用另一个循环来适应它即可迭代该级别。
$result = [];
foreach ($array as $entries) {
foreach ($entries as $key => $values) {
foreach ($values as $value) {
$result[$key][$value] = $value;
}
}
}
翻译成您在自我回答帖子中编写的代码,我认为它可能看起来像这样:
global $wp_query;
$prod_attrs = [];
foreach ($wp_query->posts as $_post) {
foreach (wc_get_product($_post->ID)->get_attributes() as $wc_attr => $wc_term_objs) {
foreach ($wc_term_objs->get_terms() as $wc_term) {
$prod_attrs[$wc_attr][$wc_term->slug] = $wc_term->slug;
}
}
}
var_export($prod_attr);
array_merge_recursive
和 splat 运算符 (...
)。
splat 运算符将解压缩可用于递归合并它们的数组。
$expected = array_merge_recursive(...$array);
此外,如果您只需要合并数组中的唯一值,您可以像这样使用
array_map
$unique = array_map('array_unique', $expected);
因为我自己一直大量使用这种方法,所以我做了一些测试,看看哪种方法更快。
分享结果:
问题:这两种方法哪个更快?
方法一:
array_map('array_unique', array_merge_recursive(...$array));
foreach
,如 mickmackusa 的回答中所述
使用大小为 5、50、100 和 500 的数组进行测试
将每个函数循环 10000 和 100000。
T1 是
array_merge_recursive
所用的时间,T2 是 foreach
所用的时间
数组大小 | 循环计数 | T1 | T2 | 更快 | 差异 |
---|---|---|---|---|---|
5 | 10,000 | 0.041 | 0.0206 | foreach | 0.0204 |
5 | 100,000 | 0.2061 | 0.2082 | 数组合并递归 | 0.002 |
5 | 500,000 | 1.0315 | 1.0611 | 数组合并递归 | 0.0296 |
50 | 10,000 | 0.046 | 0.1878 | 数组合并递归 | 0.1418 |
50 | 100,000 | 0.4452 | 1.8877 | 数组合并递归 | 1.4425 |
100 | 10,000 | 0.0697 | 0.3729 | 数组合并递归 | 0.3032 |
100 | 100,000 | 0.6795 | 3.7464 | 数组合并递归 | 3.0669 |
500 | 10,000 | 0.2542 | 1.8674 | 数组合并递归 | 1.6132 |
500 | 100,000 | 2.5359 | 18.6922 | 数组合并递归 | 16.1562 |
结论:
foreach
需要 16.1562 秒以上因此,如果您有较小的数组,请使用您想要的任何内容。对于更大的数组,一定要避免
foreach
并使用 array_merge_recursive
链接到测试沙箱