Viewed   83 times

I'm trying to select the maximum value for a particular key in a multidimensional array. I'm having trouble "getting to" the key in question...

So, the array (which is much more lengthy than what I'm posting here)

[0] => stdClass Object
    (
        [id] => 70
        [cust] => 4
        [dnum] => 1
        [upper] => Array
            (
                [0] => 66
            )

    )
[1] => stdClass Object
    (
        [id] => 43
        [cust] => 42
        [dnum] => 2
        [upper] => Array
            (
                [0] => 77
            )

    )
[2] => stdClass Object
    (
        [id] => 12
        [cust] => 3
        [dnum] => 0
        [upper] => Array
            (
                [0] => 99
            )

    )

I'm trying to find the maximum "dnum" value across the entire array, so in this example, $max = 2. I know that the max function allows me to do this, but I'm not sure how to reference the dnum element without putting the whole thing in a foreach loop, and if I do that, then max wouldn't be the function to use, right?

So, I can't exactly do this:

$max = max($myarray[]->dnum);

Is there a way for me to do this without having to recreate the entire array?

 Answers

4
$max = 0;
foreach($array as $obj)
{
    if($obj->dnum > $max)
    {
        $max = $obj->dnum;
    }
}

That function would work correctly if your highest number is not negative (negatives, empty arrays, and 0s will return the max as 0).

Because you are using an object, which can have custom properties/structures, I don't believe there are really any 'predefined' functions you can use to get it. Might as well just use a foreach loop.

You really can't get away from a foreach loop, as even internal functions use a foreach loop, it is just behind the scenes.

Another solution is

$numbers = array();
foreach($array as $obj)
{
    $numbers[] = $obj->dnum;
}
$max = max($numbers);
Saturday, October 8, 2022
4

You need to use usort, a function that sorts arrays via a user defined function. Something like:

function cmp($a, $b)
{
    if ($a["price"] == $b["price"]) {
        return 0;
    }
    return ($a["price"] < $b["price"]) ? -1 : 1;
}

usort($yourArray,"cmp")
Thursday, October 20, 2022
3

The code you already wrote almost works. The problem is that it will just immediately print the key each time it encounters one that matches the id during the foreach loop.

foreach($arr as $key => $array) {
    if ( $array['from']['id'] === $id) {
        echo $key."nn";
    }
}

If instead you store the key in a variable, then after the loop is finished, the value in the variable will be the last one, and you can just print that.

$last = "";
foreach($arr as $key => $array) {
    if ( $array['from']['id'] === $id) {
        $last = $key;
    }
}
echo $last."nn";
Friday, September 2, 2022
 
kyogs
 
3

You can iterate over your array with a help of a stack to build your toc.

$stack = &$array;
$separator = '.';
$toc = array();

while ($stack) {
    list($key, $value) = each($stack);
    unset($stack[$key]);
    if (is_array($value)) {
        $build = array($key => ''); # numbering without a title.
        foreach ($value as $subKey => $node)
            $build[$key . $separator . $subKey] = $node;
        $stack = $build + $stack;
        continue;
    }
    $toc[$key] = $key. ' ' . $value;
}

print_r($toc);

Output:

Array
(
    [1] => 1
    [1.5] => 1.5
    [1.5.3] => 1.5.3 testvalue1
    [2] => 2
    [2.6] => 2.6 testvalue2
    [3] => 3 testvalue3
    [4] => 4 testvalue4
)

You can additionally handle the level as well if you need to, but that was not clear from your question.

array_walk_recursive does not work, because it won't give you the keys of the parent element(s). See this related question as well: Transparently flatten an array, it has a good answer and is helpful for more generic cases as well.

Friday, August 26, 2022
 
1

According to the standard, it is clearly undefined behaviour as such a case is explicitly listed in the section J.2 undefined behaviour (found in an online C99 standard draft):

An array subscript is out of range, even if an object is apparently accessible with the given subscript (as in the lvalue expression a[1][7] given the declaration int a[4][5]) (6.5.6).

It can still be the case that your example will work, and actually I have seen a lot of such cases in C code; However, to be accurate, it is UB.

Monday, December 12, 2022
 
Only authorized users can answer the search term. Please sign in first, or register a free account.
Not the answer you're looking for? Browse other questions tagged :