【问题标题】:Merging objects in PHP based on a property基于属性在PHP中合并对象
【发布时间】:2018-04-18 21:14:43
【问题描述】:

我最初想做的是合并两个对象

我有一个这样的对象

{#23 ▼
  +"Name": "Consultation"
  +"ServiceId": "1024"
  +"Price": ".00"
}

另一个对象

{#362 ▼
  +"StartTime": "9:15AM"
  +"ServiceId": "1024"
}

我正在寻找一种基于 ServiceId 合并这两个对象的方法,所以我得到一个像这样的对象

   {#1 ▼
      +"Name": "Consultation"
      +"ServiceId": "1024"
      +"Price": ".00"
      +"StartTime": "9:15AM"
     }

当然,如果两个对象之间的ServiceId不匹配,就不应该合并。

关于如何解决错误的任何想法?

【问题讨论】:

  • 你的对象是什么类?
  • @bishop 这些对象不是从类中实例化的,它们是使用 json_decode() 函数生成的。
  • 改为使用json_decode($your_json,true),然后尝试array_merge
  • 您有一个包含多个对象的数组,还是每个数组中只有一个对象?
  • 有多个对象的数组,但我正在遍历它以获取一个对象并尝试比较它们

标签: php arrays object merge


【解决方案1】:

这里的想法是循环遍历 1 个数组并在另一个数组中找到(假设 1)与当前匹配的元素:

foreach ($array1 as $key => $item) {
    $other = array_filter($array2, function ($item2) use ($item) { 
        return $item2->ServiceId == $item->ServiceId;
    });
    if (!empty($other)) {
        $item->StartTime = current($other)->SomethingElse;
    }
}

因为您正在处理合并所有属性的对象,所以有点棘手。

这是一个例子:

http://sandbox.onlinephpfunctions.com/code/15a9710dea77672c4ac4165044ad2c7aae4ae234

【讨论】:

    【解决方案2】:

    您的问题似乎有两个部分。第一部分是如何合并json_decode返回的两个对象的输出。第二部分是如何在ServiceId匹配的情况下合并它们。


    第 1 部分

    json_decode 默认生成 \StdClass 类的对象。如果你想将两个 \StdClass 对象合并到第三个 \StdClass 对象中,你需要一些明智的转换:

    $a = json_decode('{"Name":"Consultation", "ServiceId":"1024", "Price":".00"}');
    $b = json_decode('{"StartTime": "9:15AM", "ServiceId": "1024"}');
    $c = (object)array_merge((array)$a, (array)$b);
    var_dump($c);
    

    这里,$a$b\StdClass 对象。将它们转换为array,合并,然后将它们转换回\StdClass

    这有点绕道而行。因此,您可以从一开始就将它们作为数组使用。 json_decode 接受一个可选的第二个参数,它指示它返回一个数组:

    $a = json_decode('{"Name":"Consultation", "ServiceId":"1024", "Price":".00"}', true);
    $b = json_decode('{"StartTime": "9:15AM", "ServiceId": "1024"}', true);
    $c = array_merge($a, $b);
    var_dump($c);
    

    这一直在数组中有效。如果您稍后希望 $c 成为 \StdClass 对象,您可以使用 $c = (object)$c; 进行转换,就像在第一个示例中所做的那样。

    See these live on 3v4l.org.


    第 2 部分

    大概,您将需要一些逻辑来迭代或以其他方式将这些对象配对在一起。你没有提到来源,但逻辑看起来像这样:

    if ($a->ServiceId == $b->ServiceId) {
        $c = (object)array_merge((array)$a, (array)$b)
    }
    

    如果您有一个对象列表,并且想要将它们全部合并在一起,您可以使用usort 的组合数组遍历行为:

    $merged = [];
    usort($objects, function ($a, $b) use ($merged) {
        $comp = strcmp($a->ServiceId, $b->ServiceId);
        if (0 === $comp) {
            $merged[] = (object)array_merge((array)$a, (array)$b)
        }
        return $comp;
    });
    var_dump($merged);
    

    这会遍历您的对象列表,并比较每个对象。如果ServiceId 匹配,则合并这两个对象并将其添加到合并列表中。共享ServiceId 的对象与列表中的对象一样多。

    【讨论】:

    • 谢谢,但这实际上不起作用,它只是合并两个对象而不考虑属性,它不是基于 ServiceId
    • 因为你问的是一个两部分的问题,但只为一个部分提供了足够的信息。
    • 对不起,我试图找到的主要功能是根据一个属性将两个对象配对在一起(这是我问题的主要标题)
    • 好吧,试试这个更新。如果它不起作用,请发布有关您的对象列表、您希望如何迭代它们以及预期输出的更多信息。
    猜你喜欢
    • 1970-01-01
    • 2021-03-29
    • 1970-01-01
    • 1970-01-01
    • 2016-10-29
    • 1970-01-01
    • 1970-01-01
    • 2020-07-27
    • 1970-01-01
    相关资源
    最近更新 更多