【问题标题】:How to merge subarrays by one key value and push qualifying values into a deeper indexed subarray?如何通过一个键值合并子数组并将限定值推送到更深的索引子数组中?
【发布时间】:2019-02-10 12:50:22
【问题描述】:

我正在尝试基于hash 值合并多维数组的子数组。

我的输入如下所示:

$images_arr = [
    [
        'hash' => '948e980ed2a36d917f1b3026b04e0016',
        'filename' => ['73315_73316_73317_LAKE13437_322.tif'],
        'filepath' => ['_TEST_DATA']
        // and there is more data here
    ],
    [
        'hash' => '948e980ed2a36d917f1b3026b04e0016',
        'filename' => ['73315_73316_73317_LAKE13437_322(1).tif'],
        'filepath' => ['_TEST_DATA/subdirectory']
        // and there is more data here
    ]
];

当一个或多个hash 值匹配时,我想合并数组并将filename 子数组值和filepath 子数组值合并到第一个。

类似这样的:

array (
  0 => 
  array (
    'hash' => '948e980ed2a36d917f1b3026b04e0016',
    'filename' => 
    array (
      0 => '73315_73316_73317_LAKE13437_322.tif',
      1 => '73315_73316_73317_LAKE13437_322(1).tif',
    ),
    'filepath' => 
    array (
      0 => '_TEST_DATA',
      1 => '_TEST_DATA/subdirectory',
    ),
    // more data here
  ),
)

该数组将包含数千条记录,我需要能够组合多个数组,其中只有 hash 值匹配。

到目前为止,我的努力是在数组上使用 foreach 来创建一个变量来缓存哈希值并检查以下循环。然后我可以提取filenamefilepath 就是这种情况。不确定这是否是最熟练的方法 - 抱歉,我仍然是 php 新手。

我的编码尝试:

$cache_hash = null;
foreach ($images_arr as $image) {
    $this_hash = $image['hash'];

    if ($cache_hash != $this_hash) {
        $cache_hash = $this_hash;
    } else {

        foreach ($image['filename'] as $filename) {
            //Get filename
        }

    }
}

【问题讨论】:

    标签: php arrays multidimensional-array merge


    【解决方案1】:

    通过根据每个数据集的 hash 值为结果数组分配临时键,您可以确定是存储第一次出现的哈希值,还是需要推送新值。

    循环完成后,移除临时(外部)键以生成您想要的结果。

    代码:(Demo)

    $array = [
        [
            'hash' => '948e980ed2a36d917f1b3026b04e0016',
            'filename' => ['73315_73316_73317_LAKE13437_322.tif'],
            'filepath' => ['_TEST_DATA']
        ],
        [
            'hash' => '948e980ed2a36d917f1b3026b04e0016',
            'filename' => ['73315_73316_73317_LAKE13437_322(1).tif'],
            'filepath' => ['_TEST_DATA/subdirectory']
        ]
    ];
    
    foreach ($array as $set) {
        if (!isset($result[$set['hash']])) {          // check if 1st occurrence of hash value
            $result[$set['hash']] = $set;             // save whole set
        } else {                                      // not 1st occurrence
            $result[$set['hash']]['filename'][] = $set['filename'][0];  // push filename value into this hash's group
            $result[$set['hash']]['filepath'][] = $set['filepath'][0];  // push filepath value into this hash's group
        }
    }
    
    var_export(array_values($result));  // re-index the result array to remove temp keys
    

    输出:

    array (
      0 => 
      array (
        'hash' => '948e980ed2a36d917f1b3026b04e0016',
        'filename' => 
        array (
          0 => '73315_73316_73317_LAKE13437_322.tif',
          1 => '73315_73316_73317_LAKE13437_322(1).tif',
        ),
        'filepath' => 
        array (
          0 => '_TEST_DATA',
          1 => '_TEST_DATA/subdirectory',
        ),
      ),
    )
    

    【讨论】:

    • 感谢您的帮助(很抱歉没有发布我的努力 - 是在正确的轨道上,但这是非常有帮助的)。将测试:)
    • 两个发布的答案都将按需要工作。 Divyesh 的答案不会费心检查是否第一次出现,因此它会在每次迭代时保存一个函数调用,但它会用相同的哈希值覆盖现有的哈希值作为结果。几乎一样。
    • 这工作得很好 - 数组中还有许多其他值,这使这些值保持不变,而无需在合并中额外重置每个值
    【解决方案2】:

    您可以使用哈希键准备数组。尝试关注。

    <?php
    // Input array set
    $input = array(
        array(
            'hash' => '948e980ed2a36d917f1b3026b04e0016',
            'filename' => array('73315_73316_73317_LAKE13437_322.tif'),
            'filepath' => array('_TEST_DATA')
        ),
        array(
            'hash' => '948e980ed2a36d917f1b3026b04e0016',
            'filename' => array('73315_73316_73317_LAKE13437_322(1).tif'),
            'filepath' => array('_TEST_DATA/subdirectory')
        ),
        array(
            'hash' => '948e980ed2a36d917f1b3026b04e0018',
            'filename' => array('73315_73316_73317_LAKE13437_321.tif'),
            'filepath' => array('_TEST_DATA/subdirectory')
        ),
        array(
            'hash' => '948e980ed2a36d917f1b3026b04e0018',
            'filename' => array('73315_73316_73317_LAKE13437_321(1).tif'),
            'filepath' => array('_TEST_DATA/subdirectory')
        ),
    );
    
    $mergeArrayWithHash = [];
    foreach ($input as $value) {
        $mergeArrayWithHash[$value['hash']]['hash'] = $value['hash'];
        $mergeArrayWithHash[$value['hash']]['filename'][] = $value['filename'][0];
        $mergeArrayWithHash[$value['hash']]['filepath'][] = $value['filepath'][0];
    }
    // Your Output array
    $result = array_values($mergeArrayWithHash);
    
    echo "<pre>";
    print_r($result);
    exit;
    

    【讨论】:

    • 是的!但这很好:)
    猜你喜欢
    • 1970-01-01
    • 2019-03-12
    • 1970-01-01
    • 1970-01-01
    • 2015-12-13
    • 2020-11-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多