2

So, I got array that looks something like this:

[65]=>
  array(2) {
    [0]=>
    array(2) {
      ["p"]=>
      float(234)
      ["sp"]=>
      float(234)
    }
    [1]=>
    array(2) {
      ["p"]=>
      float(53)
      ["sp"]=>
      float(5)
    }
    [2]...
    [3]...

  }

The idea is to go through each of 0 - N values of key 65 array, and only keep one with smallest "p", others should be removed / filtered out.

This should be done in PHP. Anyone has any idea?

I tried something like this:

$array = array_filter($array, function ($value, $key) use ($a) {
   return $a['p'] <= $value['p'];
}, ARRAY_FILTER_USE_BOTH);

where $value is 1 of elements inside 65 keyed-array and $a is current pair that is being added dynamically. So when ever its added, I go through existing elements and if its lowest, it should stay, and others get instant filtered out, but if its higher, it should automatically be filtered out.

Thank you!

3 Answers 3

2

You can use array_reduce() to get the lowest "p"-value:

$arr = [
    65 => [
        ["p" => 234, "sp" => 234],
        ["p" => 53, "sp" => 5],
        ["p" => 530, "sp" => 5],
    ]
];

function getLowestKey($carry, $item) {
    if ($item['p'] < $carry || !$carry) {
        $carry = $item['p'];
    }
    return $carry;
}

$lowestKey = array_reduce($arr[65], 'getLowestKey');
var_dump($lowestKey); // int(53)

Edit:

I just noticed there is a second part to your question, sorry about that. Once you found out the "lowest p" you can then just filter the array with that knowledge:

$lowestPs = array_filter($arr[65], function($item) use ($lowestKey) {
    return $item['p'] == $lowestKey;
});

var_dump($lowestPs);
/*
array(2) {
  [1]=>
  array(2) {
    ["p"]=>
    int(53)
    ["sp"]=>
    int(5)
  }
  [2]=>
  array(2) {
    ["p"]=>
    int(53)
    ["sp"]=>
    int(5)
  }
}
*/

This solution works even if multiple entries have the same lowest "p" value (like 53 in the above example), all of those will stay.

Sign up to request clarification or add additional context in comments.

Comments

2

Use array_column() to do an array_multisort() on the 'p' value for the records inside key 65.

<?php
$col = 'p'; // set the column you want to order on
$column = array_column($arr[65], $col);
array_multisort($column, SORT_ASC, $arr[65]);
$arr[65] = $arr[65][0]; // only keep the record with lowest 'p' value

demo

2 Comments

Pimped your code a bit, so you dont have to sort the whole $arr[65]. Code. - And if you want to keep only one value it should be $arr[65] = [<elementYouWantToKeep] (notice brackes, so its still an array)
@berend I tried, but im getting array_multisort(): Array sizes are inconsistent error. on array_multisort($column, SORT_ASC, $sortedArray[$id]);
0

If have more than 1 nested levels, you might also use a recursive approach checking the value of p, keeping the array with the lowest value.

$arrays = [
    65 => [
        ["p" => 234, "sp" => 234],
        [
            ["p" => 53,"sp" => 5],
            [
                ["p" => 54,"sp" => 1],
                ["p" => 53,"sp" => 7],
            ]
        ], [
            "p" => 255,
            "sp" => 235
        ],
    ]
];

function loop($array, &$coll = [], &$min = null)
{
    foreach ($array as $key => $value) {
        if (is_array($value)) {
            loop($value, $coll, $min);
        } elseif ($key === "p") {
            if ($min === null) $min = $value;
            if ($min > $value) {
                $coll = [$array];
                $min = $value;
                continue;
            }
            if($value === $min) $coll[] = $array;
        }
    }
    return $coll;
}

$arrays[65] = loop($arrays[65]);
var_dump($arrays);

Output

array(1) {
  [65]=>
  array(2) {
    [0]=>
    array(2) {
      ["p"]=>
      int(53)
      ["sp"]=>
      int(5)
    }
    [1]=>
    array(2) {
      ["p"]=>
      int(53)
      ["sp"]=>
      int(7)
    }
  }
}

See another php demo.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.