计算二维数组中不同的键值对

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

我需要计算数组数组中的唯一键值对(无论它们来自哪一行)。

样本输入:

$info = [
    ['car' => 'Audi', 'previous_car' => 'BMW'],
    ['car' => 'Audi', 'previous_car' => 'Seat'],
    ['car' => 'Audi', 'previous_car' => 'BMW'],
    ['car' => 'BMW',  'previous_car' => 'BMW'],
    ['car' => 'Ford', 'previous_car' => 'Seat'],
];

期望的输出:

[
    'car' => [
        'Audi' => 3,
        'BMW' => 1,
        'Ford' => 1
    ],
    'previous_car' => [
        'BMW' => 3,
        'Seat' => 2
    ]
]

我尝试使用

array_value_count()
,但我在多维数组上效果不佳。

php arrays multidimensional-array grouping counting
5个回答
4
投票

如果您运行的是 PHP 5.5,您可以使用:

$newArray = array(
    'car' => array_count_values(array_column($info, 'car')),
    'previous_car' => array_count_values(array_column($info, 'previous_car'))
);
var_dump($newArray);

对于 5.5 之前的 PHP 版本

$newArray = array(
    'car' => array_count_values(
        array_map(
            function($value) {
                return $value['car'];
            },
            $info
        )
    ),
    'previous_car' => array_count_values(
        array_map(
            function($value) {
                return $value['previous_car'];
            },
            $info
        )
    )
);
var_dump($newArray);

2
投票

以更面向对象的方式,您可以按如下方式解决它

$values = new ArrayObject();
$iterator = new RecursiveArrayIterator($info);
iterator_apply($iterator, 'countDistinct', array($iterator, $values));

function countDistinct($iterator, $values) {
    while ( $iterator -> valid() ) {
        if ( $iterator -> hasChildren() ) {
            countDistinct($iterator -> getChildren(), $values);
        } else {
            if (!$values->offsetExists($iterator->key())) {
                $values->offsetSet($iterator->key(), new ArrayObject());
            }

            if (!$values->offsetGet($iterator->key())->offsetExists($iterator->current())) {
                $values->offsetGet($iterator->key())
                    ->offsetSet($iterator->current(), 1);
            } else {
                $values->offsetGet($iterator->key())
                    ->offsetSet($iterator->current(),
                $values->offsetGet($iterator->key())->offsetGet($iterator->current()) + 1);
            }
        }

        $iterator -> next();
    }
}

当然,在这个例子中你没有避免循环。但是使用 ArrayObject 和 RecursiveArrayIterator,您将拥有一些内存和性能优势。

此结果将与您的预期结果完全匹配,您可以使用 ArrayObject 的 getIterator() 函数轻松地对其进行迭代。


0
投票

以下是可能对您有帮助的内容:

$returnArray = array('car' => NULL, 'previous_car' => NULL);

foreach($info as $newInfo) {
    $returnArray['car'][] = $newInfo['car'];
    $returnArray['previous_car'][] = $newInfo['previous_car'];
}

$ret['car'] = array_count_values($returnArray['car']);
$ret['previous_car'] = array_count_values($returnArray['previous_car']);

var_dump($ret);

返回:

array (size=2)
  'car' => 
    array (size=3)
      'Audi' => int 3
      'BMW' => int 1
      'Ford' => int 1
  'previous_car' => 
    array (size=2)
      'BMW' => int 3
      'Seat' => int 2

0
投票

我不认为我会为此任务推荐任何本机功能。使用嵌套的

foreach()
循环可能是最干净的。使用每一行的键和值作为第一级和第二级键,并在每次出现时增加计数。

代码:(演示

$result = [];
foreach ($info as $row) {
    foreach ($row as $k => $v) {
        $result[$k][$v] = ($result[$k][$v] ?? 0) + 1;
    }
}
var_export($result);

-1
投票

您可以编写一个函数来对您的数据进行排序,但现在检查一下: http://www.php.net/manual/en/function.array-multisort.php

© www.soinside.com 2019 - 2024. All rights reserved.