【问题标题】:PHP Array combine values with same string keyPHP数组将值与相同的字符串键组合起来
【发布时间】:2020-04-19 05:50:20
【问题描述】:

我有以下似乎很常见的问题,但不知道哪个数组函数可能适用于以下格式:

(已经尝试过array_mergearray_merge_recursivearray_combinearray_splice,但没有按预期工作。)

Array
(
    [0] => Array
        (
            [r_id] => 11
            [r_sid] => RC
            [d_id] => 2
        )

    [1] => Array
        (
            [r_id] => 7
            [r_sid] => RC
            [c_id] => 51
        )

    [2] => Array
        (
            [r_id] => 6
            [r_sid] => JN
            [c_id] => 52
        )

    [3] => Array
        (
            [r_id] => 7
            [r_sid] => JN
            [c_id] => 51
        )

    [4] => Array
        (
            [r_id] => 7
            [r_sid] => LG
            [c_id] => 51
        )

    [5] => Array
        (
            [r_id] => 7
            [r_sid] => BN
            [c_id] => 51
        )

    [6] => Array
        (
            [r_id] => 6
            [r_sid] => IVS
            [c_id] => 52
        )

    [7] => Array
        (
            [r_id] => 7
            [r_sid] => IVS
            [c_id] => 51
        )

)

现在,我需要通过常见的r_sid & c_id 键合并这个数组值;唯一的特殊情况是如果有一个d_id 键而不是c_id,那么我们将它与数组中具有相似r_sid 的任何值合并/组合。

如果这样更容易理解,最终的解决方案需要如下所示:

Array
(
    [0] => Array
        (
            [r_id] => 11,7
            [r_sid] => RC
            [d_id] => 2
            [c_id] => 51 
        )


    [1] => Array
        (
            [r_id] => 6,7
            [r_sid] => JN, IVS
            [c_id] => 52,51
        )

)

与任何人都不匹配的r_sid 值需要被丢弃。

感谢任何帮助。非常感谢!

【问题讨论】:

  • 没有具体的函数来处理你想要的各种组合,你需要自己写一些东西。
  • 您如何决定不将所有带有c_id = 51c_id = 52 的值合并在一起?
  • 只有 d_id 优先,并且 , 存在于一个或两个值中。因此,如果存在,它将需要找到与 r_sid 匹配的其他值。否则,这个数组填充的总是 c_id。
  • @nigel ren:我确实理解它更具体一些,但我一直在编写自己的子函数,最终来到这个数组。只是无法解决最后一个匹配项。
  • 您能否将到目前为止的代码添加到问题中,因为完成它可能比做一些全新的事情更容易(尽管也可能会建议这样做)。

标签: php arrays multidimensional-array array-merge array-combine


【解决方案1】:

这是我对如何合并数组的最佳解释的一段代码:

// filter out r_sid values which only occur once
$sid_values = array_count_values(array_column($array, 'r_sid'));
$array = array_filter($array, function ($a) use ($sid_values) { return $sid_values[$a['r_sid']] > 1; });

// combine arrays on r_sid values
$result = array();
foreach ($array as $arr) {
    $sid = $arr['r_sid'];
    // push data to arrays
    $result[$sid]['r_sid'] = $sid;
    $result[$sid]['r_id'][] = $arr['r_id'];
    if (isset($arr['c_id'])) $result[$sid]['c_id'][] = $arr['c_id'];
    if (isset($arr['d_id'])) $result[$sid]['d_id'][] = $arr['d_id'];
}

// combine all the c_id values into a string
array_walk($result, function (&$a) {
    if (isset($a['c_id'])) $a['c_id'] = implode(',', $a['c_id']);
});

// now combine any r_sid values that have the same set of c_id values
$output = array();
foreach ($result as $res) {
    $cid = $res['c_id'];
    // push data to arrays
    $output[$cid]['c_id'] = $cid;
    $output[$cid]['r_sid'] = array_merge($output[$cid]['r_sid'] ?? array(), array($res['r_sid']));
    $output[$cid]['r_id'] = array_merge($output[$cid]['r_id'] ?? array(), $res['r_id']);
    if (isset($res['d_id'])) $output[$cid]['d_id'] = array_merge($output[$cid]['d_id'] ?? array(), $res['d_id']);
}

// combine the r_sid, r_id and d_id values into a string
array_walk($output, function (&$a) {
    $a['r_sid'] = implode(',', $a['r_sid']);
    $a['r_id'] = implode(',', array_unique($a['r_id']));
    if (isset($a['d_id'])) $a['d_id'] = implode(',', $a['d_id']);
});

// remove the associative keys
$output = array_values($output);

输出:

Array
(
    [0] => Array
        (
            [c_id] => 51
            [r_sid] => RC
            [r_id] => 11,7
            [d_id] => 2
        )
    [1] => Array
        (
            [c_id] => 52,51
            [r_sid] => JN,IVS
            [r_id] => 6,7
        )
)

Demo on 3v4l.org

【讨论】:

  • @user7616631 不用担心。但是......它适用于你给出的非常小的例子。我不知道当你在一些严肃的数据上尝试它时它会有多好......
猜你喜欢
  • 1970-01-01
  • 2013-02-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-01-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多