【问题标题】:Efficient way of reducing multidimensional array减少多维数组的有效方法
【发布时间】:2017-06-09 01:00:25
【问题描述】:

我有以下数组需要用内部值总和来减少

0 => array:116 [
  121 => array:3 [
    "number" => 121
    "name" => "Some Name 1"
    "value" => "2.222"
  ]
  116 => array:3 [
    "number" => 116
    "name" => "Some Name 2"
    "value" => "1.111"
  ]
  1 => array:3 [
    "number" => 1
    "name" => "Some Name 3"
    "value" => "1.232"
  ]
]
1 => array:116 [
  121 => array:3 [
    "number" => 121
    "name" => "Some Name 1"
    "value" => "1.111"
  ]
  116 => array:3 [
    "number" => 116
    "name" => "Some Name 2"
    "value" => "2.222"
  ]
  1 => array:3 [
    "number" => 1
    "name" => "Some Name 3"
    "value" => "3.111"
  ]
]

应该是这样的

0 => array:116 [
  121 => array:3 [
    "number" => 121
    "name" => "Some Name 1"
    "value" => "3.333"
  ] 
  116 => array:3 [
    "number" => 116
    "name" => "Some Name 2"
    "value" => "3.333"
  ]
  1 => array:3 [
    "number" => 1
    "name" => "Some Name 3"
    "value" => "4.343"
  ]
]

假设输入数组的长度未定义,但复杂度/嵌套级别最大为 2,根据输入计算结果数组的有效/有效方法是什么。

影响 PHP 5.6 和 PHP 7+ 的优化解决方案

【问题讨论】:

标签: php arrays algorithm multidimensional-array reduce


【解决方案1】:

从您的示例输入数组看来,所有numbers 都表示在每个子数组中(1211161)。如果您的实际项目并非如此,请使用更准确/真实的示例数据更新您的问题。

我的方法通过多维数组“减少”两次,以首先根据数字键隔离数据库列,然后在类似键选择中隔离value 元素。

代码:(Demo)

$array = [
    [
        121 => [ "number" => 121, "name" => "Some Name 1", "value" => "2.222" ],
        116 => [ "number" => 116, "name" => "Some Name 2", "value" => "1.111" ],
          1 => [ "number" =>   1, "name" => "Some Name 3", "value" => "1.232" ]
    ],
    [
        121 => [ "number" => 121, "name" => "Some Name 1", "value" => "1.111" ],
        116 => [ "number" => 116, "name" => "Some Name 2", "value" => "2.222" ],
          1 => [ "number" =>   1, "name" => "Some Name 3", "value" => "3.111" ]
    ]
];

$all_numbers=array_keys($array[0]);  // generate a 1-dim array of `number` values
foreach($all_numbers as $number){
    $array[0][$number]['value']=array_sum(array_column(array_column($array,$number),'value'));
}
$array=[$array[0]];  // only keep the first subarray's data

var_export($array);

输出:

array (
  0 => 
  array (
    121 => 
    array (
      'number' => 121,
      'name' => 'Some Name 1',
      'value' => 3.333,
    ),
    116 => 
    array (
      'number' => 116,
      'name' => 'Some Name 2',
      'value' => 3.333,
    ),
    1 => 
    array (
      'number' => 1,
      'name' => 'Some Name 3',
      'value' => 4.343,
    ),
  ),
)

【讨论】:

  • @harehman 如果这不适合您的项目,请说明我需要更正的内容。
  • @harehman 这很干净/直接,对吧?这对您的所有情况都有效吗?让我们将您的问题推向解决方案。令人震惊的是,该网站上 30% 的 php 问题没有获得绿色勾号。
【解决方案2】:

我更新了可以带很多孩子的功能。在 repl 中,我链接了两个我在数组键的 0 和 1 中添加了一个额外的孩子。

// Merege $a[0] and $a[1] and sum up the `value` key 

$merge_sum = array_map(function($key, ...$a) {
  $merged = array_merge(...$a);
  $merged['value'] = array_sum(array_column($a, 'value'));
  return [ $key => $merged ];
}, array_keys($a[0]), ...$a);

// // Fix array array keys

$final = array_reduce($merge_sum, function($c, $i) {
  $concat = $c + $i;
  return $concat;
}, []);

var_dump($final);

在这个 repl 上测试它; https://repl.it/Id7T/6

【讨论】:

  • 谢谢,但实际上这只是一个示例。真正的数组由 100 多个子元素组成,同样使用 function 并不比 looping through foreach
  • 循环总比函数调用快,如果有错请纠正我
  • 我相信这是真的,这只是我解决问题的一种方式。权衡最终将是可维护性。您破坏代码的可能性较小,如果速度最重要,我会编写一个完成相同任务的循环并比较权衡。
  • @harehman 我已经更新了能够处理多个孩子的功能。
猜你喜欢
  • 2015-06-18
  • 2020-05-06
  • 1970-01-01
  • 2013-04-15
  • 2011-03-25
  • 2021-02-18
  • 1970-01-01
  • 1970-01-01
  • 2019-05-31
相关资源
最近更新 更多