php 在二维数组中创建新列,该列表示另一个二维数组中相关值的计数

sczxawaw  于 2023-02-15  发布在  PHP
关注(0)|答案(2)|浏览(164)

我有一个数组,包含传入邮件的数据,看起来像这样:

$incomingMail = [
   0 => [
      'title' => 'Title 1',
      'areaCode' => 101
   ],
   1 => [
      'title' => 'Title 2',
      'areaCode' => 101
   ],
   2 => [
      'title' => 'Title 3',
      'areaCode' => 102
   ]
];

和另一个包含区域名称和代码的数组,该数组如下所示:

$areaArr = [
   0 => [
      'name' => 'Area 1',
      'code' => 101
   ],
   1 => [
      'name' => 'Area 2',
      'code' => 102
   ],
   2 => [
      'name' => 'Area 3',
      'code' => 103
   ],
   3 => [
      'name' => 'Area 4',
      'code' => 104
   ]
];

我想创建一个包含incomingMail数组的计数的数组,基于areaArr的代码,它看起来像这样:

$areaWithMailCount = [
   0 => [
      'areaName' => 'Area 1',
      'areaCode' => 101,
      'mailCount' => 2
   ],
   1 => [
      'areaName' => 'Area 2',
      'areaCode' => 102,
      'mailCount' => 1
   ],
   2 => [
      'areaName' => 'Area 3',
      'areaCode' => 103,
      'mailCount' => 0
   ],
   3 => [
      'areaName' => 'Area 4',
      'areaCode' => 104,
      'mailCount' => 0
   ]
];

我尝试过循环这些数组并添加基于区号的条件,但结果不是我想要的,代码如下所示:

$areaWithMailCount = [];

foreach($areaArr as $area) {
   foreach($incomingMail as $mail) {
      if($mail['areaCode'] == $area['code']) {
         $areaWithMailCount[] = [
            'areaName' => $area['name'],
            'areaCode' => $area['code'],
            'mailCount' => count($mail)
         ];
      }
   }
}

以上代码的结果如下所示:

[
  0 => [
    "areaName" => "Area 1"
    "areaCode" => 101
    "mailCount" => 2
  ],
  1 => [
    "areaName" => "Area 1"
    "areaCode" => 101
    "mailCount" => 2
  ],
  2 => [
    "areaName" => "Area 2"
    "areaCode" => 102
    "mailCount" => 2
  ]
];

有什么办法吗?

u5i3ibmn

u5i3ibmn1#

我知道这个问题已经得到了回答,但只是为了增加一点更干净的方式。
这基本上使用了与https://stackoverflow.com/a/75443993/1791606相同的过程,但是对于注解来说太大了,所以我把它放在了答案中。

$mailCounts = array_count_values(array_column($incomingMail, 'areaCode'));

$areaWithMailCount = array_map(fn(array $area) => [
    'areaName'  => $area['name'],
    'areaCode'  => $area['code'],
    'mailCount' => $mailCounts[$area['code']] ?? 0,
], $areaArr);
ovfsdjhp

ovfsdjhp2#

使用嵌套循环效率很低--这将使服务器在搜索合格值时执行大量不必要的循环。
相反,只循环$incomingMail数组一次,并填充$areaArr数组在迭代时可以引用的查找数组。如果$areaArr中的code与查找数组中的任何键都不相关,则将该值默认为0。
代码:(Demo

$lookup = [];
foreach ($incomingMail as $row) {
    $lookup[$row['areaCode']] = ($lookup[$row['areaCode']] ?? 0) + 1;
}

$result = [];
foreach ($areaArr as $row) {
    $result[] = [
        'areaName' => $row['name'],
        'areaCode' => $row['code'],
        'mailCount' => $lookup[$row['code']] ?? 0
    ];
}

var_export($result);

上述2循环代码片段的函数式等效代码如下所示:Demo

$lookup = array_reduce(
    $incomingMail,
    function($result, $row) {
        $result[$row['areaCode']] = ($result[$row['areaCode']] ?? 0) + 1;
        return $result;
    }
);

var_export(
    array_map(
        fn($row) =>
            [
                'areaName' => $row['name'],
                'areaCode' => $row['code'],
                'mailCount' => $lookup[$row['code']] ?? 0
            ],
        $areaArr
    )
);

或者甚至:Demo

var_export(
    array_map(
        function($row) use ($incomingMail) {
            static $lookup;
            $lookup ??= array_reduce(
                $incomingMail,
                function($result, $row) {
                    $result[$row['areaCode']] = ($result[$row['areaCode']] ?? 0) + 1;
                    return $result;
                }
            );
            return [
                'areaName' => $row['name'],
                'areaCode' => $row['code'],
                'mailCount' => $lookup[$row['code']] ?? 0
            ];
        },
        $areaArr
    )
);

相关问题