Find the maximum and parent value in an array - php

I searched many thread but i can't find this solution
I have this Array
Array
( [0] => [1] => Array ( [0] => 2019-01-11T23:30:00CET [1] => -12.6 ) [2] => [3] => Array ( [0] => 2019-01-11T23:20:00CET [1] => -12.5 ) [4] => [5] => Array ( [0] => 2019-01-11T23:10:00CET [1] => -12.6 ) [10] => [11] => Array ( [0] => 2019-01-11T22:40:00CET [1] => -12.4 )
I found the path to have the maximum or minimum value ( Column [1] ) from this Array but i need to find the relative Parent
(example the minimum -12.6 is in the [1][0] as 2019-01-11T22:20:00CET)
of this two values that are show in the first column ( Column[0] )
Thanks

If you use array_column() to extract the second column of your data, then you can use min() or max() with that array to pick which one you want. This code then extracts the ones that match using a foreach() and if to check if it matches (not exactly sure what you want as output, but this should help)...
$source = [["2019-01-11T23:30:00CET", -12.6],
["2019-01-11T23:20:00CET", -12.5],
["2019-01-11T23:10:00CET", -12.6]
];
$extract = min(array_column($source, 1)); // or use max()
$output = [];
foreach ($source as $key => $element) {
if ( $element[1] == $extract ) {
// Matches, so add to output
$output[$key] = $element[0];
}
}
print_r($output);
will give
Array
(
[0] => 2019-01-11T23:30:00CET
[2] => 2019-01-11T23:10:00CET
)
You could use array_filter() to extract the matching rows, but a foreach() is enough for a straightforward thing like this (IMHO).
If there is a possibility of blank values or strings in the value column, this may confuse the min() as it will consider the values and compare them as strings, to ensure they are all compared as numbers you can add...
$values = array_map("floatval", array_column($source, 1));
$extract = min($values); // or use max()
The array_map("floatval",... goes through the list and converts them all to float values.

Also, here's a generalized algorithm-sketch for "finding the max in some array", expressed as pseudo-code:
"Leave quietly" if the array is empty, or throw an exception.
Otherwise, assume that the first element in the array is the biggest one.
Now, loop through the remaining elements, testing if each one is, in fact, bigger than the "biggest one" that you have so far. If so, select it as the "biggest."
When the loop is finished, return your answer.
Now – this is what a geek would call "an O(n) algorithm," which is to say that its execution-time will be "on the order of" the number of elements in the array. Well, if this is a "one-off" requirement, that's fine. Whereas if what you actually want to do is to get "more than one" max-element, sorting the array (once, then holding on to the sorted result ...) becomes significantly better, because the sort is going to be O(log(n)) ... "on the order of some logarithm of the number of elements," ... and the subsequent cost of "popping off" elements from that sorted array becomes non-existent.
There are other ways to do it, of course – trees and such - but I've already blathered-on too long here.

Related

Find partial string inside array

I have this array from an AJAX request:
array (
[0] => 'lat,long#id_1'
[1] => 'lat,long#id_2'
[2] => 'lat,long#id_3'
)
The problem here is I'm not gonna have always a 'correct-ordered' array like that, so it may look like this one:
array (
[0] => 'lat,long#id_1'
[1] => 'lat,long#id_2'
[2] => 'lat,long#id_3'
[3] => 'lat,long#id_1'
[4] => 'lat,long#id_3'
[5] => 'lat,long#id_2'
)
I need to get the last array value of every id_X (currently only 3 ids):
array (
[3] => 'lat,long#id_1'
[4] => 'lat,long#id_3'
[5] => 'lat,long#id_2'
)
How can I find each last value of that array based on partial string (id_X)?
First do a reverse sort to ensure the latest values are parsed first. Then run them through a loop, matching the partial string to get the ID, adding the data to an array if the ID index doesn't exist yet. Last values will be added to your array, others will be neglected. Something like this:
rsort($ajaxy);
$lasts = [];
foreach($ajaxy as $str) {
$id = substr($str, strrpos($str, '#') + 1);
if (!isset($lasts[$id])) {
$lasts[$id] = $str;
}
}
var_dump($lasts);
If you have a huge array, and you know the amount of IDs you will be getting, you can add in a check to terminate the loop when all required IDs have been added in to avoid redundant processing.
Otherwise, don't bother with the reverse sort, and simply keep overwriting previous values 'til the end, but I find this a cleaner approach. ^_^

2 or more arrays from a list

I am quite not able to get the logic for my requirement.
Lets consider I have an array
Array
(
[0] => 1
[1] => 1
[2] => 2
[3] => 1
[4] => 3
[5] => 3
)
I would like to split the below array on the basis if the array element matches its previous element.
i.e in the above example value at [1] matches the value at [0]. Hence put it into the same array as [0]. Now check if the value at [2] matches the value at [1] if it matches put it into the same array, if not put it into a different array. The process continues.
Below is an example of the desired outpout.
Array
(
[0] => 1
[1] => 1
)
Array
(
[0] => 2
)
Array
(
[0] => 1
)
Array
(
[0] => 3
[1] => 3
)
Thanks for your help in advance.
Justin
you can obtain that result in a loop checking on previous element. the output can be an array of arrays! (or anything you would prefer.. do your thing here)
$array1 = array(1, 1, 2, 1, 3, 3);
$output_array=array();
$previous_value="";
$output_array_index=0;
foreach ($array1 as $value) {
if($value != $previous_value){
$output_array_index+=1;
}
$output_array[$output_array_index][]=$value;
$previous_value=$value;
}
print_r($output_array);
so, let me know if you need more pointers! array logic is fun, and php will let you do alot, out of the box. though this specific need is not covered, have a look when you have a minute # the manual, it'll save you time in the future, guarantee http://php.net/manual/en/ref.array.php
This question is a bit confusing but doesn't sound too difficult to implement if I'm understanding it correctly. All you need to do is have a temporary array (or array list) that checks user input. If that user input happens to be the same as the previous input (you can keep a counter variable and check to see if ArrayList.get(counter) == ArrayList.get(counter-1)). Keep adding things to this temporary arrayList and once you have a number that is different, just iterate through the arraylist and add it to a new array.
Another question you have to consider is how you are going to store all these arrays. For that you may want to create an ArrayList containing Arrays. That way after you find user input that is different from the previous input you can just use the toArray method provided with the ArrayList class and add it to the ArrayList containing all of your separate Arrays!
Hope this helps!

Comparing arrays until I have a unique array

I have the following multidimensional array called $existing_combinations
Array
(
[0] => Array
(
[1] => 6
[2] => 7
[3] => 9
)
[1] => Array
(
[1] => 1
[2] => 21
[3] => 9
)
[2] => Array
(
[1] => 1
[2] => 7
[3] => 9
)
)
I then generate a new array ($new_combination) which has a combination of the same set of values. Example:
Array
(
[1] => 6
[2] => 21
[3] => 9
)
I then test if $new_combination exists in $existing_combinations with the following in the hope that I will end with a unique combination in $new_combination:
foreach($existing_combinations as $key => $combination){
while($new_combination == $combination){
$new_combination = generateNewCombination();
}
}
The problem is that if $new_combination matches an array that is not at index 0, then when I generate a new combination I am at risk of this matching a $combination that has already been tested against (and will not be tested again).
Sorry if this is a simple one but I'm struggling to think of how I can ensure $new_combination will always end up unique.
Any ideas?
Thanks
You can use in_array in this case, because php compares arrays as value. So, the code can be:
while(in_array($new_combination = generateNewCombination(), $existing_combinations));
print_r($new_combination);
I wrote the below before realizing that in_array can also see if an array exists within an array. So you can simply do this:
if (!in_array($new_combination, $existing_combinations)) {
// It's unique.
}
In the below outdated bit, see the note on using sort, if a different sequence of the same numbers isn't considered unique for your purposes.
[ For Entertainment ]
May not be the most elegant way around, but I would simply do this to keep it simple:
$combo_hashes = [];
// Implode the existing combos into strings.
foreach($existing as $vals) {
$combo_hashes[] = implode(':', $vals);
}
Then, all you need to check with your new combo is:
// Check if the "hash"-string already exists.
if (!in_array( implode(':', $new_combo), $combo_hashes)) {
// ... and we're unique.
}
This presumes that you consider [1,3,2] different from [2,1,3]. If they are equivalent (I don't know what your use case is), you should sort($vals); before you generate the check-strings.
Merge all the second level arrays and run array_unique() to get rid of the duplicate values.

Foreach and unset()

Ran into a little snag and wondering if there is a "best practices" way around it.
So I just learned that "A php foreach will execute on the entire array regardless. Test unsetting a value that is next in iteration. It will iterate on the offset, but the value will be null. – Kevin Peno Dec 22 '09 at 21:31" from How do you remove an array element in a foreach loop?
It's the first part of that that is messing with me. I'm iterating through an array with foreach. It's a search function so I'm removing the element I just searched for, so when the loop runs again its minus that element.
I do NOT want to reindex if at all possible, although if I have to I can.
Array
(
[0] => Array
(
[0] => a
[1] => aa
[2] => aaa
)
[1] => Array
(
[0] => b
[1] => bb
[2] => bbb
)
[2] => Array
(
[0] => c
[1] => cc
[2] => ccc
)
[3] => Array
(
[0] => d
[1] => dd
[2] => ddd
)
)
foreach($array as $key=>$value) {
$searchresult[] = search function returns various other keys from array
foreach($searchresult as $deletionid) {
unset($array[$deletionid]);
}
}
So on the first iteration it uses $array[0] obviously but the $searchresults might return 4,5,6,7. So those keys are removed from $array.
Yet the foreach loop still iterates through those and gives me back a bunch of empty arrays.
I did read How does PHP 'foreach' actually work? and I get some of it.
Thanks
In my opinion, the best way to remove array elements based on indexes is to use the array_* set of functions, like array_diff and array_intersect (or array_diff_key and array_intersect_key in your situation).
$indexes_to_remove = array(2,3,4);
$indexes_to_remove = array_flip($indexes_to_remove);
$array = array_diff_key($array,$indexes_to_remove);
If the array is guaranteed to be exhausted at some point, you can use this:
while (true) {
$searchresult[] = search function returns various other keys from array
foreach($searchresult as $deletionid) {
unset($array[$deletionid]);
}
if (count($array) === 0) {
break;
}
}
And yes I know while (true) is pretty evil, but I find in cases like these it does exactly what is needed.
If you want to prevent it from infinite looping you could always add a variable, increment each iteration, and break when it reaches a high value that should never happen (like 10 * count($array))

Remove items from array with value above/below threshold

What's the most efficient way to remove items from an array in php where the value is greater than a pre-determined threshold, e.g. given an array
Array
(
[0] => 1.639
[1] => 2.168
[4] => 1.897
[6] => 4.129
)
I would like to remove all the items with a value greater than e.g. 2, preserving key associations, to give
Array
(
[0] => 1.639
[4] => 1.897
)
I know I can do this using a foreach() loop but it seems that there should be a more elegant way.
No matter what you use, the array has to be looped through but you can hide it by using array_filter:
function test($var) { return $var < 2; }
$data = array_filter($data, 'test');

Categories