基于属性合并PHP中的对象

时间:2017-11-06 16:27:49

标签: php arrays object merge

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

我有一个像这样的对象

{#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不匹配,则不应合并。

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

2 个答案:

答案 0 :(得分:1)

您的问题似乎有两个部分。第一部分是如何合并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共享的对象,将会发生这种情况。

答案 1 :(得分:0)

这里的想法是循环遍历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