문제

I have the following array of PHP stdclass objects (actually mine has hundreds of indices, but the goal is the same) and I am having trouble finding the most efficient way to determine programmatically with PHP which stdclass object occurs most often in the array.

If, for example, the standard class object at index 0 occurred most often (which obviously it does not), then I would like to echo out "1 , 1024" or something similar.

Array
(
    [0] => stdClass Object
        (
            [a] => 1
            [b] => 1024
        )

    [1] => stdClass Object
        (
            [a] => 4
            [b] => 4096
        )

    [2] => stdClass Object
        (
            [a] => 4
            [b] => 4096
        )

    [3] => stdClass Object
        (
            [a] => 4
            [b] => 4096
        )

    [4] => stdClass Object
        (
            [a] => 4
            [b] => 4096
        )

    [5] => stdClass Object
        (
            [a] => 4
            [b] => 4096
        )

    [6] => stdClass Object
        (
            [a] => 4
            [b] => 4096
        )

    [7] => stdClass Object
        (
            [a] => 4
            [b] => 6144
        )

    [8] => stdClass Object
        (
            [a] => 4
            [b] => 6144
        )

    [9] => stdClass Object
        (
            [a] => 8
            [b] => 6144
        )

    [10] => stdClass Object
        (
            [a] => 8
            [b] => 6144
        )

    [11] => stdClass Object
        (
            [a] => 8
            [b] => 8192
        )

    [12] => stdClass Object
        (
            [a] => 8
            [b] => 8192
        )

    [13] => stdClass Object
        (
            [a] => 8
            [b] => 8192
        )

    [14] => stdClass Object
        (
            [a] => 8
            [b] => 8192
        )
)

Thanks!

도움이 되었습니까?

해결책 4

Although I didn't go with either answer, specifically, they were both very helpful in helping me come up with this solution.

$x = array();
$count = 0;

for ($i = 0; $i < count($myArray); $i++) {
    if ($myArray[$i]->a != $myArray[$i - 1]->a 
        && $myArray[$i]->b != $myArray[$i - 1]->b) {
        $count = 0;
    }

    $x[$myArray[$i]->a . '|' . $myArray[$i]->b] = ++$count;
}

print_r($x);

Which results in the following output.

Array
(
    [1|1024] => 1
    [4|4096] => 5
    [4|6144] => 3
    [8|6144] => 2
    [8|8192] => 4
)

Then just grab the largest value from that array.

다른 팁

Search all registers, storing the [a] ocurrences in an array/map and sort by count?

As it turns out, the == operator will tell you if objects are equal. So you can just loop through each item in the array, and build another array that keeps track of how often each value is encountered. Then you'll need to sort the resulting array by count, so you know which object occurred most often.

$orig = array(
    (object)array('a'=>3, 'b'=>'4096'),
    (object)array('a'=>2, 'b'=>'2048'),
    (object)array('a'=>2, 'b'=>'2048'),
    (object)array('a'=>1, 'b'=>'1024'),
    (object)array('a'=>1, 'b'=>'1024'),
    (object)array('a'=>2, 'b'=>'2048'),
    (object)array('a'=>1, 'b'=>'1024'),
    (object)array('a'=>2, 'b'=>'2048'),
);

$countArray = array();

foreach($orig as $obj) {
    $didCount = false;
    foreach($countArray as $counted) {
        if ($counted->value == $obj) {
            $counted->count++;
            // if we found a match, record that fact and 
            // break out of this loop early.
            $didCount = true;
            break;
        }
    }

    // If no match was found, then this is the first time 
    // we've seen this particular value
    if (!$didCount)
        $countArray[] = (object)array(
            'count' => 1,
            'value' => $obj,
        );
}

// To find the most frequent item, best way is to 
// sort $countArray by count.
usort($countArray, function($left, $right) {
    return $right->count - $left->count ;
});

print_r($countArray[0]);

I think that you need something like this right? I think that is pretty fast. If you need check instances of the same object or similar you can generate the key with spl_object_hash function instead of concatenate the values as i do.

$foo = (object)['a' => 0, 'b' => 1024];
$bar = (object)['a' => 4, 'b' => 4096];
$qux = (object)['a' => 8, 'b' => 6144];

$array = [];
foreach(range(1, 1024) as $i) $array[] = $foo;
foreach(range(1, 4096) as $i) $array[] = $bar;
foreach(range(1, 6144) as $i) $array[] = $qux;

$result = [];
array_walk($array, function($obj) use (&$result) {
    $key = implode('|', get_object_vars($obj));
    if ( isset($result[$key]) ) $result[$key]++;
    else $result[$key] = 1;
});

arsort($result);
print_r($result);

Returns:

Array
(
    [8|6144] => 6144
    [4|4096] => 4096
    [0|1024] => 1024
)

Regards.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top