【问题标题】:Recursively merge like indexes递归合并类似索引
【发布时间】:2018-05-18 03:55:09
【问题描述】:

我有一个数组,其中包含我试图合并在一起的类似索引。由于某种原因,我无法理解它。

原始数组

$seperateArray = json_decode('[
{ "tier1": "Group1", "tier2": "Blue", "tier3": "Round", "tier4": "Harold" },
{ "tier1": "Group1", "tier2": "Blue", "tier3": "Round", "tier4": "Arthur" },
{ "tier1": "Group1", "tier2": "Blue", "tier3": "Round", "tier4": "Tom" },
{ "tier1": "Group2", "tier2": "Blue", "tier3": "Round", "tier4": "Beth" },
{ "tier1": "Group3", "tier2": "Blue", "tier3": "Round", "tier4": "Peter" }]', true);

把它变成:

{
    "Group1": {
        "Blue": {
            "Round": [
                "Harold",
                "Arthur",
                "Tom"
            ]
        }
    },
    "Group2": {
        "Blue": {
            "Round": [
                "Peter"
            ]
        }
    }
}

这是我目前所处的位置,但我不知道我是否朝着正确的方向前进。

$newCombined = array();

//this each statement will show every tier 1-4 array object
foreach($seperateArray as $s) {

    if(!array_key_exists($s['tier1'], $newCombined) $newCombined[$s['tier1']] = array();
    if(!array_key_exists($newCombined[$s['tier1']][$s['tier2']], $newCombined[$s['tier1']])) $newCombined[$s['tier1']][$s['tier2']] = array();
    //.. and so on

}

【问题讨论】:

  • 它有没有可能拥有另一个维度?
  • @pr1nc3 只会有 tier1-4 的索引,但值可能完全不同

标签: php arrays


【解决方案1】:

如果只有tier4 可以产生一个数组,那么循环和分配就是一件简单的事情(如果你对静音通知没问题的话):

$array = json_decode('...', true);
$new = [];

foreach ($array as $e)
    @$new[$e['tier1']][$e['tier2']][$e['tier3']][] = $e['tier4'];

echo json_encode($new, JSON_PRETTY_PRINT); # to print what you asked for

为了让这个任务不那么神秘:

foreach ($array as $e) {
    list($t1, $t2, $t3, $t4) = array_values($e);
    @$new[$t1][$t2][$t3][] = $t4;
}

$new返回到原始数组:

$original = [];

foreach (array_keys($new) as $t1)
    foreach (array_keys($new[$t1]) as $t2)
        foreach (array_keys($new[$t1][$t2]) as $t3)
            foreach ($new[$t1][$t2][$t3] as $t4)
                $original[] = [
                    'tier1' => $t1,
                    'tier2' => $t2,
                    'tier3' => $t3,
                    'tier4' => $t4,
                ];

echo json_encode($original, JSON_PRETTY_PRINT);

【讨论】:

  • 这太完美了!谢谢西迪尔!现在完全有道理。没有考虑过突如其来的通知
  • 感谢@bryan,很乐意提供帮助。禁止通知通常会引发与宗教争论的讨论……但如果您对此表示满意,那么在这种情况下它确实可以简化事情。我想说这是@ 为数不多的合法用途之一。如果您不想使用,则必须检查每个密钥是否存在,然后在必要时创建它。否则,让 PHP 自动创建它们(就像许多语言一样)并且忽略在这种情况下它只会使用 @ 生成的通知。在我看来,非常方便。
  • 是的,这只是设置一些数据,并没有在生产中持续使用,所以这对我来说是一个完美的用例。我很珍惜时间。
  • 这是超级随机的,但是你知道如何从结束数组倒退到开始数组吗? @sidyll
  • @bryan 我更新了答案以包含解决该问题的建议:)
【解决方案2】:

Sidyll 的回答很完美,但由于我正在研究自己的解决方案,所以我也会发布它:

$input = json_decode('[
  { "tier1": "Group1", "tier2": "Blue", "tier3": "Round", "tier4": "Harold" },
  { "tier1": "Group1", "tier2": "Blue", "tier3": "Round", "tier4": "Arthur" },
  { "tier1": "Group1", "tier2": "Blue", "tier3": "Round", "tier4": "Tom" },
  { "tier1": "Group2", "tier2": "Blue", "tier3": "Round", "tier4": "Beth" },
  { "tier1": "Group3", "tier2": "Blue", "tier3": "Round", "tier4": "Peter" }]', true);

$output = [];

foreach($input as $row) {
  $recursion = &$output;
  foreach($row as $key => $value) {
    if ($key != 'tier4' && !isset($recursion[$value])) {
      $recursion[$value] = [];
    }
    if ($key == 'tier4') {
      $recursion[] = $value;
    } else {
      $recursion = &$recursion[$value];
    }
  }
}

var_dump($output);

array(3) { ["Group1"]=> array(1) { ["Blue"]=> array(1) { ["Round"]=> array(3) { [0]=> 字符串(6)“哈罗德”[1]=>字符串(6)“亚瑟”[2]=>字符串(3)“汤姆”}}}[“Group2”]=>数组(1){[“蓝色”] => array(1) { ["Round"]=> array(1) { [0]=> string(4) "Beth" } } } ["Group3"]=> array(1) { ["Blue" ]=> array(1) { ["Round"]=> &array(1) { [0]=> string(5) "Peter" } } } }

不是特别自豪,但它确实有效。

【讨论】:

  • 这是一个非常好的策略!也感谢您发布它。
  • 谢谢你,@sidyll :) TBH,看到你的方法后感觉有点脏。
  • 一点也不脏,这是一个聪明的方法,可以在比我更多的情况下使用,因为它以灵活的方式遍历数据。
猜你喜欢
  • 1970-01-01
  • 2018-03-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-10-21
  • 2022-12-07
  • 2018-06-12
  • 2020-01-27
相关资源
最近更新 更多