合并两个数组,如果前缀相同则用第二个数组的值覆盖第一个数组的值。

5
我可以为您翻译。需要合并两个包含文件列表和它们的修订版本的数组。
例如:
第一个数组:
['A[1]', 'B[2]', 'C[2]', 'D[2]']

第二个:

['B[3]', 'C[4]', 'E[4]', 'F[2]', 'G[2]']

如我所说,我可以合并两个数组,但会用第二个数组中的数据覆盖第一个数组中与字母/文件名相冲突的部分。

我使用了这个正则表达式来仅获取文件名(去除版本号)。我不确定这一点是否正确:

/\[[^\)]+\]/

我需要的结果是这样的:
['A[1]', 'B[3]', 'C[4]', 'D[2]', 'E[4]', 'F[2]', 'G[2]']

目前我正在使用PHP4。


1
array_merge在我的情况下无法工作,因为我需要覆盖现有数据。此外,我需要处理与文件相关的修订号(在一个大字符串中)。 - Pierre-Olivier
3个回答

4

something like:

function helper() {
  $result = array();

  foreach (func_get_args() as $fileList) {
    foreach ($fileList as $fileName) {
      list($file, $revision) = explode('[', $fileName, 2);
      $revision = trim($revision, ']');
      $result[$file] = !isset($result[$file]) ? $revision : max($result[$file], $revision);
    }
  }

  foreach ($result as $file => $revision) {
    $result[$file] = sprintf('%s[%s]', $file, $revision);
  }

  return array_values($result);
}

$a = array('A[1]', 'B[2]', 'C[2]', 'D[2]');
$b = array('B[3]', 'C[4]', 'E[4]', 'F[2]', 'G[2]');

print_r(helper($a, $b));

demo: http://codepad.org/wUMMjGXC


你之前发布的代码完美运行!我忘了提到,但我们仍在使用PHP4 :( 但感谢你的答案,它完美地运行着。 - Pierre-Olivier
又改了一下(有点)。我猜在php4中也应该可以工作。func_get_args()部分可能会有问题。可能需要使用额外的变量而不是直接使用结果。 - Yoshi
这个版本在PHP4下完美运行。非常感谢你的帮助!非常感激。 - Pierre-Olivier

2
一种方法是将两个数组都映射到。
filename => filename[revision]

这样的,以致于
Array
(
    [0] => A[1]
    [1] => B[2]
    [2] => C[2]
    [3] => D[2]
)

成为。
Array
(
    [A] => A[1]
    [B] => B[2]
    [C] => C[2]
    [D] => D[2]
)

然后使用array_merge(覆盖具有相同键的条目)。

类似这样:

function map($array) {
    $filenames = array_map(function($value) {
        return strstr($value, '[', false);
    }, $array);
    return array_combine($filenames, $array);
}

$result = array_merge(map($array1), map($array2));

如果您想要数字索引,可以在结果上调用array_values。上面的代码需要PHP 5.3,但很容易使它与早期版本兼容。另一个注意事项是,它只能在数组中文件名唯一时起作用。 演示(PHP 5.2版) 参考:array_map, strstr, array_combine, array_merge

非常感谢您的回答,但我忘了提到我们仍在使用PHP4 :( - Pierre-Olivier
嗯,我注意到了 :D 但我仍然会留下答案供那些不使用 PHP 4 的人参考 ;) - Felix Kling

0

只需遍历每个数组并在将值推入结果数组时分配临时键。按顺序迭代数组,以便第二个数组的值覆盖第一个数组的值。循环结束后,您可以通过调用array_values()来丢弃临时/分组键。

代码:(演示

$a = ['A[1]', 'B[2]', 'C[2]', 'D[2]'];
$b = ['B[3]', 'C[4]', 'E[4]', 'F[2]', 'G[2]'];

$result = [];
foreach ($a as $v) {
    $result[strtok($v, '[')] = $v;
}
foreach ($b as $v) {
    $result[strtok($v, '[')] = $v;
}
var_export(array_values($result));

输出:

array (
  0 => 'A[1]',
  1 => 'B[3]',
  2 => 'C[4]',
  3 => 'D[2]',
  4 => 'E[4]',
  5 => 'F[2]',
  6 => 'G[2]',
)

因为你的输入数组在它们的分组字母方面是逻辑上独特的,这个函数式片段将提供与上面脚本相同的结果:(演示)

var_export(
    array_values(
        array_reduce(
            array_merge($a, $b),
            function($result, $v) {
                $result[strtok($v, '[')] = $v;
                return $result;
            }
        )
    )
);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接