在 PHP 中获取数组的差异

问题描述 投票:0回答:2

在我的场景中,绘画列表位于 json 格式的列中。绘画列表包含文件名、绘画名称和查看次数。我想删除列表中的一幅画。但我没有成功。这是我的代码:

$paintings = '[["24ef9-70076-4358c-48386.jpg","La Donna Gravida","649"],["a7972-065a9-4c0f9-723d1.jpg","Madonna and Child with the Book","1254"],["b054c-df208-0f600-e884e.jpg","Madonna del Granduca","1457"]]';
$painting = 'a7972-065a9-4c0f9-723d1.jpg';
$difference  = array_diff((array)json_decode($paintings), (array)$painting);
echo json_encode(array_values($difference));

我试图得出以下结论:

[["24ef9-70076-4358c-48386.jpg","La Donna Gravida","649"],["b054c-df208-0f600-e884e.jpg","Madonna del Granduca","1457"]]
但是我收到这样的错误:
Notice: Array to string conversion in...
你能帮助我吗?

php arrays array-difference
2个回答
2
投票

json 字符串中没有带有键的对象,因此通过解码创建的数组不会与键关联。下面显示了解决您的问题的一种可能方法(直接的方法)。

$out = array();
foreach(json_decode($paintings, true) as $p)
  if (!in_array($painting, $p))
    $out[] = $p;

echo json_encode(array_values($out));

另一种方式

$out = array_filter(json_decode($paintings, true), function($el) use($painting) {
  return !in_array($painting, $el);  
});

echo json_encode(array_values($out));

原因是因为

["a7972-065a9-4c0f9-723d1.jpg","Madonna and Child with the Book","1254"]
不是具有键或值
a7972-065a9-4c0f9-723d1.jpg
的元素 - 它是另一个数组,您必须检查整个子数组中值是否存在或仅检查其第一个元素。在这种情况下
!in_array($painting, $el)
可以替换为
$painting != $el[0]


0
投票
  • 使用经典循环。如果只需要一个匹配项,则在找到匹配项后中断循环。 否则,如果多行可能符合删除条件,请省略

    break
    关键字并允许循环完全遍历数组。 演示

    foreach ($paintings as $index => $row) {
        if ($row[0] === $painting) {
            unset($paintings[$index]);
            break; // unless multiple rows might qualify
        }
    }
    var_export($paintings);
    

  • 从 PHP8.4 及更高版本开始,使用

    array_find_key()
    查找第一个符合条件的行的索引并取消设置。 演示

    $index = array_find_key(
         $paintings,
         fn($row) => $row[0] === $painting
    );
    if ($index !== null) {
         unset($paintings[$index]);
    }
    var_export(array_values($paintings));
    

  • 使用

    array_filter()
    遍历整个数组,保留所有与黑名单值不匹配的行。 演示

    var_export(
         array_values(
             array_filter(
                 $paintings,
                 fn($row) => $row[0] !== $painting
             )
         )
    );
    

  • 可以使用
  • array_udiff()
    ,但当黑名单数据超过一个值时更合适。在这种情况下,将列入黑名单的值作为单行的单独元素传递。 演示

    var_export(
         array_values(
             array_udiff(
                 $paintings,
                 [[$painting]],
                 fn($a, $b) => $a[0] <=> $b[0]
             )
         )
    );
    
© www.soinside.com 2019 - 2024. All rights reserved.