2017-07-17 19 views
-1

我有一個對象數組。PHP Array - 計數部分重複

我想統計兩個值完全匹配的數組項的總數。

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個數組項目有藍色牛仔褲。

+0

任何兩個值,或者特別是Line和Color? –

回答

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 
+0

這很好,應該是被接受的答案。 – localheinz

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 
+0

這不是通用的,它專用於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);