PHP数组 - 计算部分重复项

时间:2017-07-17 16:27:39

标签: php arrays

我有一组对象。

我想计算两个值完全匹配的数组项的总数。

Array
(
    [0] => stdClass Object
        (
            [Job] => stdClass Object
                (
                    [ID] => 123
                    [Line] => Shirt
                    [Color] => Blue
                 )
        )
    [1] => stdClass Object
        (
            [Job] => stdClass Object
                (
                    [ID] => 456
                    [Line] => Jeans
                    [Color] => Blue
                 )
        )
    [2] => stdClass Object
        (
            [Job] => stdClass Object
                (
                    [ID] => 789
                    [Line] => Jeans
                    [Color] => Blue
                 )
        )
)

在这个简化的例子中,我想要计算有2个具有蓝色牛仔裤的数组项。

3 个答案:

答案 0 :(得分:2)

最好的方法可能是在数据库中使用索引:

<?php
$json = <<<JSON
[
  {"Job":{"ID":123,"Line":"Shirt","Color":"Blue"}},
  {"Job":{"ID":456,"Line":"Jeans","Color":"Blue"}},
  {"Job":{"ID":789,"Line":"Jeans","Color":"Blue"}}
]
JSON;
$data = json_decode($json);
$index = [];
$counter = 0;
array_walk($data, function(\stdClass $entry) use (&$index, &$counter) {
    $key = $entry->Job->Line . '|' . $entry->Job->Color;
    if (!in_array($key, $index)) {
        $index[] = $key;
    } else {
        $counter++;
    }
});
print_r($counter);

输出显然是:

1

答案 1 :(得分:0)

只需使用一个好的旧循环。

$count = 0; //Initialize the number of matches to 0
//Loop through each item (obviously)
foreach($array as $item) {
    //Check if the required properties match.
    //If they do, increment $count by 1
    if($item->Job->Line=="Jeans" && $item->Job->Color=="Blue") ++$count;
}
//Do whatever is required with the value of $count

答案 2 :(得分:0)

这是使用简单递归的另一种方法。您可以设置所需的匹配数量,它将找到任何属性的匹配项(没有任何修复)。我将它包装在一个类中以保存所有内容:

<?php
class MatchFind {

    // This can be set to any number of matches desired 
    const ELEMENTS_TO_FIND = 2;

    public static function count ($aObjs) {

        // Cannot compare elements unless there are 2
        if (sizeof($aObjs) <= 1) {
            return 0;
        }

        // Get the top element from the array
        $oTop       = array_shift($aObjs);
        $aTopProps  = (array) $oTop->Job;

        // Get the number of matches, moving from end to start,
        // removing each match from the array
        $iMatchObjs = 0;
        for ($n = sizeof($aObjs); $n > 0; $n--) {
            $oCompare = $aObjs[$n-1];
            $iMatch = 0;
            foreach ((array) $oCompare->Job as $sKey => $sValue) {
                if (isset($aTopProps[$sKey]) && $aTopProps[$sKey] === $sValue) {
                    ++$iMatch;
                }
            }
            if ($iMatch >= self::ELEMENTS_TO_FIND) {
                unset($aObjs[$n-1]);
                ++$iMatchObjs;
            }
        }
        reset($aObjs);
        return ($iMatchObjs + self::count($aObjs));
    }
}

// Declare the objects 
$aAllObjs = [
    (object)[ 'Job' => (object)['ID' => 123,
                                'Line' => 'Shirt',
                                'Color' => 'Blue'] ],
    (object)[ 'Job' => (object)['ID' => 456,
                                'Line' => 'Jeans',
                                'Color' => 'Blue'] ],
    (object)[ 'Job' => (object)['ID' => 789,
                                'Line' => 'Jeans',
                                'Color' => 'Blue'] ],
];

echo MatchFind::count($aAllObjs);