wordpress 展平多维数组并删除重复的子数组值

9rnv2umw  于 2023-11-17  发布在  WordPress
关注(0)|答案(4)|浏览(187)

我需要在woocommerce中对我的产品属性的数据结构进行排序,对每个属性及其值进行分组。
我的阵列现在

  1. array (size=5)
  2. 0 =>
  3. array (size=1)
  4. 'pa_color' =>
  5. array (size=1)
  6. 0 => string 'red' (length=3)
  7. 1 =>
  8. array (size=1)
  9. 'pa_color' =>
  10. array (size=1)
  11. 0 => string 'red' (length=3)
  12. 2 =>
  13. array (size=2)
  14. 'pa_color' =>
  15. array (size=1)
  16. 0 => string 'gray' (length=4)
  17. 'pa_modello' =>
  18. array (size=1)
  19. 0 => string 'modello2' (length=8)
  20. 3 =>
  21. array (size=1)
  22. 'pa_color' =>
  23. array (size=1)
  24. 0 => string 'yellow' (length=6)
  25. 4 =>
  26. array (size=0)
  27. empty

字符串
我需要合并如下内容:

  1. array (size=1)
  2. 'pa_color' =>
  3. array (size=1)
  4. 0 => string 'red' (length=3)
  5. 1 => string 'gray' (length=4)
  6. 2 => string 'yellow' (length=6)
  7. 'pa_modello' =>
  8. array (size=1)
  9. 0 => string 'modello2' (length=8)


将相同键的值分组到一个数组中。
thanks in advance

332nm8kg

332nm8kg1#

  1. global $wp_query;
  2. $obj = get_queried_object();
  3. foreach ($wp_query->posts as $_post) {
  4. $_product = wc_get_product($_post->ID);
  5. $wc_attr_objs = $_product->get_attributes();
  6. $prod_attrs = [];
  7. foreach ($wc_attr_objs as $wc_attr => $wc_term_objs) {
  8. $prod_attrs[$wc_attr] = [];
  9. $wc_terms = $wc_term_objs->get_terms();
  10. foreach ($wc_terms as $wc_term) {
  11. array_push($prod_attrs[$wc_attr], $wc_term->slug);
  12. var_dump($prod_attrs);
  13. }
  14. }
  15. $totals[] = $prod_attrs;
  16. }

字符串

展开查看全部
l2osamch

l2osamch2#

假设$array是你的数组:

  1. foreach ($array as $item)
  2. {
  3. if ($item['pa_color']['0']) $color[ $item['pa_color']['0'] ] = $item['pa_color']['0'];
  4. if ($item['pa_modello']['0']) $modello[$item['pa_modello']['0']] = $item['pa_modello']['0'];
  5. // 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
  6. }
  7. foreach ($color as $c) $newArray['pa_color'][] = $c;
  8. foreach ($modello as $m) $newArray['pa_modello'][] = $m;

字符串
这个应该可以了
编辑:
对于动态属性注解:

  1. foreach ($array as $item)
  2. foreach (array_keys($item) as $key) // getting the keys ex: pa_color
  3. {
  4. if ($item[$key]['0']) {
  5. $temparray[$key][ $item[$key]['0'] ] = $item[$key]['0'];
  6. }
  7. // 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
  8. // the temparray will contain in its keys ($key) the pa_color , pa_module.. etc
  9. // each of them will be an array with the key=value approach .. in case having two "red" it will not duplicate
  10. }
  11. // finally making it zero based array
  12. foreach ($temparray as $key=>$item) // ex: $temparray['pa_color']['red'] = 'red'
  13. foreach ($item as $value) // ex: $item['red'] = 'red'
  14. $newArray[$key][] = $value; // ex: $newArray['pa_color'][0] = 'red';


它看起来很复杂..我找不到更好的方法。

展开查看全部
5ktev3wc

5ktev3wc3#

循环遍历第一级条目,然后添加一个嵌套循环,从子数组中的所需键和值创建变量。
因为最深的子数组中只有一个元素,所以可以在嵌套循环中使用“数组解构”将唯一的元素值赋为$value
通过将$value声明为结果数组中深度值的键,确保输出中的值是唯一的。
如果您确实希望重新索引子数组,可以使用array_map()array_values()来实现这一点--但仅在必要时才这样做。
产品编号:(Demo

  1. $result = [];
  2. foreach ($array as $entries) {
  3. foreach ($entries as $key => [$value]) {
  4. $result[$key][$value] = $value;
  5. }
  6. }
  7. var_export($result);

字符串
输出量:

  1. array (
  2. 'pa_color' =>
  3. array (
  4. 'red' => 'red',
  5. 'gray' => 'gray',
  6. 'yellow' => 'yellow',
  7. ),
  8. 'pa_modello' =>
  9. array (
  10. 'modello2' => 'modello2',
  11. ),
  12. )


p.s.如果你的深层子数组可能有多个元素,那么只需要用另一个循环来适应这个级别。

  1. $result = [];
  2. foreach ($array as $entries) {
  3. foreach ($entries as $key => $values) {
  4. foreach ($values as $value) {
  5. $result[$key][$value] = $value;
  6. }
  7. }
  8. }


翻译成你在自我回答帖子中写的代码,我认为它可能看起来像这样:

  1. global $wp_query;
  2. $prod_attrs = [];
  3. foreach ($wp_query->posts as $_post) {
  4. foreach (wc_get_product($_post->ID)->get_attributes() as $wc_attr => $wc_term_objs) {
  5. foreach ($wc_term_objs->get_terms() as $wc_term) {
  6. $prod_attrs[$wc_attr][$wc_term->slug] = $wc_term->slug;
  7. }
  8. }
  9. }
  10. var_export($prod_attr);

展开查看全部
mwecs4sa

mwecs4sa4#

合并最简单的方法是在数组的数组上使用array_merge_recursive和splat操作符(...)。
splat操作符将解包数组,可用于递归合并它们。

  1. $expected = array_merge_recursive(...$array);

字符串
另外,如果您只需要合并数组中的唯一值,则可以像这样使用array_map

  1. $unique = array_map('array_unique', $expected);


more about splat operator

* 评论后编辑 *

因为我自己一直在大量使用这种方法,所以我做了一些测试,看看哪一种更快。
分享成果:
问:这两种方法哪个更快?
方法一:array_map('array_unique', array_merge_recursive(...$array));
方法2:使用foreach,如mickmackusa的回答中所述
使用大小为5、50、100和500的阵列进行测试
每个函数循环10000和100000。
T1是array_merge_recursive所花费的时间,T2是foreach所花费的时间
| 数组大小|循环计数|T1| T2|快|diff|
| --|--|--|--|--|--|
| 5 |一万|0.041| 0.0206| foreach| 0.0204|
| 5 |十万|0.2061| 0.2082|数组归并递归|零点零二|
| 5 |五十万|一点零三一五|1.0611|数组归并递归|0.0296|
| 50 |一万|零点四六|一千八百七十八|数组归并递归|0.1418|
| 50 |十万|0.4452|一点八八七七|数组归并递归|一点四四二五|
| 100 |一万|零六九七|0.3729|数组归并递归|0.3032|
| 100 |十万|0.6795|三四六四|数组归并递归|三点零六六九|
| 500 |一万|0.2542| 1.8674|数组归并递归|一点六一三二|
| 500 |十万|二点五三五九|18.6922|数组归并递归|十六点一五六二|
结论:
1.对于小型数组,使用什么并不重要,我只在500,000次循环后才注意到差异
1.不同的是当你使用更大的数组时。当使用计数为500 foreach的数组时,需要多花16.1562秒。
因此,如果你有较小的数组,你可以使用任何你想要的。对于较大的数组,一定要避免foreach,而使用array_merge_recursive
链接到test sandbox

展开查看全部

相关问题