【问题标题】:Array merge on basis of same keys but different keys value should add as separate array基于相同键的数组合并,但不同的键值应添加为单独的数组
【发布时间】:2020-06-17 07:29:06
【问题描述】:

我有如下粘贴的数据。我想根据名称进行组合,即 abc 名称模板采用不同的语言,我希望它在信息名称、类别及其所有语言中位于同一索引上。

[{
    "name": "abc",
    "category": "new_cat",
    "selectedLanguage": [{
        "de": "Deutsch",
        "de_status": "APPROVED"
    }]
}, {
    "name": "abc",
    "category": "new_cat",
    "selectedLanguage": [{
        "en": "English",
        "en_status": "APPROVED"
    }]
}, .... 

如上所述,我希望将结果作为 json 粘贴在下面。

[{
    "name": "abc",
    "category": "new_cat",
    "selectedLanguage": [{
        "de": "Deutsch",
        "de_status": "APPROVED"
    }, {
        "en": "English",
        "en_status": "APPROVED"
    }]
},...{
    "name": "unique_temp",
    "category": "TICKET_UPDATE",
    "selectedLanguage": [{
        "en": "English",
        "en_status": "REJECTED"
    }, {
        "fr": "French",
        "fr_status": "REJECTED"
    }]

}]

我已经为它写了一个代码

$trimArr; //this data array
$finalTempArr = array();
$finalArr = array();


 foreach ($trimArr as $tr) {
       $checkIfExist = $this ->in_array_r($wr['name'], $finalArr);
       if($checkIfExist == false){
           $finalTempArr['name'] =  $tr['name'];
           $finalTempArr['category'] =  $tr['category'];
           $finalTempArr['selectedLanguage'] =  $tr['selectedLanguage'];

       }else {
           array_push($finalTempArr['selectedLanguage'],$tr['selectedLanguage']);
       }

        array_push($finalArr, $finalTempArr);
   }
   echo json_encode($finalArr); 

function in_array_r($needle, $haystack, $strict = false) {
    foreach ($haystack as $item) {
        if (($strict ? $item === $needle : $item == $needle) || (is_array($item) 
        && $this->in_array_r($needle, $item, $strict))) {
            return true;
        }
    }

    return false;
}

【问题讨论】:

  • 如果传入数组中的每一行在selectedLanguage子数组中只有一个孩子,那么你应该降低数据结构的复杂性,只写语言和语言状态。如果您在这些子数组中可能有多组语言,那么一切都很酷。

标签: php arrays logic


【解决方案1】:

您可以使用array_reduce 来完成它:

$result = array_reduce($array, static function(array $carry, array $item) {
    $key = $item['name'] . $item['category'];

    if (isset($carry[$key])) {
        $carry[$key]['selectedLanguage'] = array_merge($carry[$key]['selectedLanguage'], $item['selectedLanguage']);
    } else {
        $carry[$key] = $item;
    }

    return $carry;
}, []);

如果你在减少后需要新的密钥,那么你可以在结果上使用array_values

$result = array_values($result);

【讨论】:

    【解决方案2】:

    一个简单的 foreach 循环就可以了。

    我想根据名字进行组合

    因此,在您对数据进行分组和合并时,只需使用 name 作为临时键即可。

    代码:(Demo)

    $result = [];
    foreach (json_decode($json, true) as $row) {
        if (!isset($result[$row['name']])) {
            $result[$row['name']] = $row;
        } else {
            $result[$row['name']]['selectedLanguage'] = array_merge($result[$row['name']]['selectedLanguage'], $row['selectedLanguage']);
        }
    }
    var_export(array_values($result));
    

    我想得越多,您的子数组结构可能不适合目的。如果您最终要搜索可用语言以返回语言状态,最好将数组结构设置为“查找”。换句话说,每个selectedLanguage 子数组应该是一个平面关联数组,使用language 作为键,language_status 作为值。这看起来像"en" => "APPROVED"

    或者,如果您的脚本已经依赖en 键来查找适当的值,则将en 保留为键并从en 创建一个平面关联子数组。我不能 100% 自信地说你应该做什么,但我有理由相信你的数据结构可以改进。一旦你放弃了索引子数组结构,你就可以实现a recursive merge/replace technique.

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-02-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-19
    • 1970-01-01
    • 2020-08-13
    相关资源
    最近更新 更多