Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/262.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/extjs/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
通过在PHP中匹配对象字段,在单个数组中组合对象值_Php_Arrays - Fatal编程技术网

通过在PHP中匹配对象字段,在单个数组中组合对象值

通过在PHP中匹配对象字段,在单个数组中组合对象值,php,arrays,Php,Arrays,我一直在四处挖掘,试图以尽可能干净的方式解决这个问题,但还没有找到正确的方法 我有一个这样的对象数组: $myArray = [ {field: "Diameter", measurement: 15, count: 4}, {field: "Diameter", measurement: 16, count: 1}, {field: "Diameter", measurement: 17, count: 15}

我一直在四处挖掘,试图以尽可能干净的方式解决这个问题,但还没有找到正确的方法

我有一个这样的对象数组:

$myArray = [
    {field: "Diameter", measurement: 15, count: 4},
    {field: "Diameter", measurement: 16, count: 1},
    {field: "Diameter", measurement: 17, count: 15},
    {field: "Width", measurement: 7, count: 12},
    {field: "Width", measurement: 8, count: 8},
    {field: "Brands", measurement: "blah", count: 1},
    {field: "Brands", measurement: "doubleBlah", count: 3},
    {field: "Brands", measurement: "blah", count: 1},
    {field: "Brands", measurement: "doubleBlah", count: 3},
    {field: "Brands", measurement: "blah", count: 12}
    ]

我需要组合具有重复测量场的对象,并像这样组合计数:

$myBetterArray = [
    {field: "Diameter", measurement: 15, count: 4},
    {field: "Diameter", measurement: 16, count: 1},
    {field: "Diameter", measurement: 17, count: 15},
    {field: "Width", measurement: 7, count: 12},
    {field: "Width", measurement: 8, count: 8},
    {field: "Brands", measurement: "blah", count: 14},
    {field: "Brands", measurement: "doubleBlah", count: 6},
    ]
 [
    {"field":"Brands","measurement":"blah","count":1},
    {"field":"Brands","measurement":"blah","count":1},
    {"field":"Brands","measurement":"blah","count":12},
    {"field":"Brands","measurement":"doubleBlah","count":3},
    {"field":"Brands","measurement":"doubleBlah","count":3},
    {"field":"Diameter","measurement":15,"count":4},
    {"field":"Diameter","measurement":16,"count":1},
    {"field":"Diameter","measurement":17,"count":15},
    {"field":"Width","measurement":7,"count":12},
    {"field":"Width","measurement":8,"count":8}
 ]
是否可以使用类似于array_map的东西或同样干净且不太冗长的东西来完成?如果有任何帮助,我将不胜感激。

基于这样“隐藏”的密钥、已知的数据格式以及问题的编写方式(“尽可能干净的方式”,“不太冗长”),我只需选择foreach():

在可以使用密钥的中间数组中处理数据(如果不这样做,以后搜索给定的密钥对会更复杂),然后使用另一个foreach将结果以所需格式组合在一起

这对于两个级别应该足够了。另外,最好将代码放在一个函数中,以防止$\u im污染名称空间

(object)[]
是一种将数组强制转换为对象(stdClass)的简单方法,因为这似乎就是问题中的数据格式


??0
为当前
$\u im[$item->field][$item->measurement]
尚未存在时的情况创建一个起始值(即,每次有新字段时,测量对)。写入时间比使用isset()短。

首先对数组进行排序,以便所有可能连接的测量值都是连续的;这将允许您仅检查连续元素

这种方法使更改每个记录的字段规范(也称为签名或综合征)变得更容易,使用的内存更少,并且在非常长的数组中可以抵抗“Schlemiel the Painter”问题

$keys = [ 'field', 'measurement' ];

uasort($array, function($item1, $item2) use ($keys) {
    foreach ($keys as $key) {
        if ($item1[$key] === $item2[$key]) {
            continue;
        }
        if ($item1[$key] < $item2[$key]) {
            return -1;
        }
        return 1;
    }
    return 0;
});
// This is to be sure that the array will reencode as a JSON array
$array = array_values($array);
现在,扫描合并具有相同密钥综合征的计数的数组

$j = -1;
$advance = true;
foreach ($array as $i => $row) {
    if ($j >= 0) {
        $advance = false;
        foreach ($keys as $key) {
            if ($array[$i][$key] !== $array[$j][$key]) {
                $advance = true;
                break;
            }
        }
        if (!$advance) {
            // Row $i is a duplicate of row $j
            $array[$j]['count'] += $array[$i]['count'];
        }
    }
    if ($advance) {
        // Row $i is moved in row $j
        $j++;
        if ($j !== $i) {
            $array[$j] = $array[$i];
        }
    }
}
// All rows past j must be deleted
$array = array_slice($array, 0, $j+1);
阵列现在是:

[
    {"field":"Brands","measurement":"blah","count":14},
    {"field":"Brands","measurement":"doubleBlah","count":6},
    {"field":"Diameter","measurement":15,"count":4},
    {"field":"Diameter","measurement":16,"count":1},
    {"field":"Diameter","measurement":17,"count":15},
    {"field":"Width","measurement":7,"count":12},
    {"field":"Width","measurement":8,"count":8}
]

我似乎无法在PHP7.4.3上运行此代码。如果我将
compact()
替换为
$res[]=['field'=>$field',measurement'=>$measurement',count'=>$count]
(我仍然收到一些E_通知消息)@LSerni My bad,compact()需要变量名,而不是变量本身。我必须将这行更改为:
$\u im[$item['field']][$item['measurement']=$item['count']+($\u im[$item['field']][$item['measurement']]?\0)但是这样做的技巧,它不是太冗长,谢谢@BRose好的,$item是数组,不是对象?对不起,我当时误解了数据。很高兴它成功了!
[
    {"field":"Brands","measurement":"blah","count":14},
    {"field":"Brands","measurement":"doubleBlah","count":6},
    {"field":"Diameter","measurement":15,"count":4},
    {"field":"Diameter","measurement":16,"count":1},
    {"field":"Diameter","measurement":17,"count":15},
    {"field":"Width","measurement":7,"count":12},
    {"field":"Width","measurement":8,"count":8}
]