Fast searching approach in multidimensional array - php

The above searching I want with minimum number of code and with best serach performance.
I want to generate an array from this above array by putting logic like:
ALL "EMA" key values of array should not be allowed to match with "JACKSON" key values. Similarly all "JACKSON" key values of the same array are not allowed to fall in any value of "EMA" key. So the resulting array would be like shown below:
Array
(
[0] => Array
(
[EMA] => A
[JACKSON] => B
)
[2] => Array
(
[EMA] => D
[JACKSON] => E
)
)
I want to know the best approach with lesser code to achieve this. The method I have used seems so lengthy. I want a shorter and robust approach.

I think this might be a solution:
$emas = array();
$jacksons = array();
foreach($array as $element){
$emas[] = $element['EMA'];
$jacksons[] = $element['JACKSON'];
}
//array_intersect returns the common values in the arrays as an array
if(!empty(array_intersect($emas, $jacksons))){
echo 'array is invalid!';
}

Related

Find the maximum and parent value in an array

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.

Compare Dates from Array with multidimensional array [duplicate]

I have a multidimensional array like this:
Array (
[0] => Array
(
[time] => 1364685993
[memberid] => 131
)
[1] => Array
(
[time] => 1364685994
[memberid] => 133
)
[2] => Array
(
[time] => 1364685995
[memberid] => 141
)
)
and a single-dimensional array like this:
Array (
[0] => 131
[1] => 141
[2] => 191
[3] => 205
)
Now I want to remove all Sub-arrays from multidimensional arrays that DOES NOT contain the memberid value from normal array ?
In this case only Subaray[1] to be removed from multidimensional array as it's 'memberid' key value (133) doesn't show in normal array. Those arrays are actually pretty big, so I am not sure what would be fastest way to do it ?
$normalArray = array_flip($normalArray);
$multiDimArray = array_filter($multiDimArray, function ($elem) use ($normalArray) {
return isset($normalArray[$elem['memberid']]);
});
Requires exactly two iterations, one over each array. Key lookups using $normalArray[$elem['memberId']] are blazingly fast. May have some memory overhead due to the functional nature and copies of arrays, use a traditional loop and unset if that's an issue.
First, I would flip the $nomal array to get constant lookup time into the array, like this:
$normal = array_flip( $normal);
Then, you just have to filter the $multidimensional_array by the $normal array with a simple lookup:
$filtered = array_filter( $multidimensional_array, function( $el) use( $normal) {
return isset( $normal[ $el['member_id'] ]);
});
Don't have access to development resources at the moment to test but this should work.
foreach($members as $member => $property) {
if (!in_array($property['member_id'], $id_array)) {
unset($members[$member]);
}
}
$id_array is the 1-dimensional matrix (array) you've put in your question.
Instead of filtering the database results after the fact you may want to use the single-dimensional array in the database query itself.
We do not know what the query, you are using, looks like, but something along these lines would do it:
// The ids from the file
$use_ids = array(131, 141, 191, 205);
// Create a list for the IN clause
$ids = '(' . implode(',', $use_ids) . ')';
// Create the query
$query = <<< SQL
SELECT time, memberid
FROM some_table
WHERE ...
AND memberid IN {$ids}
ORDER BY time
SQL;
// Execute the query, etc.
It is always a good idea to let the SQL handle as much filtering of content as possible.

Unable to convert array according to date time value in php

I have a array named $itemIds and it consists of the following datas. The key is the items id and the value is the date time that can be converted to a readable date.What I want to do is simply sort the order of the array according to the value (time). I'm totally new to php and some examples or tips would be great ! I would love to hear from you.
Array
(
[10477] => 1508898726
[10549] => 1508898744
[10891] => 1508898752
)
If I use this code I get the following data from the print_r.
if (isset($itemIds)) {
$time = array();
foreach ($itemIds as $key => $val) {
print_r($key.'=>'.date('m/d/Y H:i:s', $val));
}
}
The problem starts from here.I want to sort(asc & desc) the $itemsIds according to the date time.
10477 => 10/25/2017 11:32:06
10549 => 10/25/2017 11:32:24
10891 => 10/25/2017 11:32:32
I want to sort the data then use array_keys($shopIds) to change it like the following data
Array
(
[0] => 10477
[1] => 10549
[2] => 10891
)
I think the easier approach would be to sort the data and then flip it so the keys are values. If you look at your data you are initially dealing with actual timestamps from what I can see. Use them, don't change them to strings. I say this because you are just causing yourself to do extra work without any reason and introducing a layer of complexity that is not needed. Instead I would do the following:
$array = [
10477 => 1508898726,
10549 => 1508898744,
10891 => 1508898752,
];
arsort($array);
$sorted_array = array_values(array_flip($array));
This is easy to read and does not involve the extra function. The result you are left with is:
Array
(
[0] => 10477
[1] => 10549
[2] => 10891
)
A little explanation:
I am using arsort() or asort() (based on the direction you want to sort) in order to sort based on the values in the array.
Then I use array_flip() on the array in order to swap the keys and values.
And last I am using array_keys() to reset the indexes in the array and maintain its sort.
Hope this helps!

How do I reorganize an array in PHP?

I am trying to figure out how to reorganize an array..
I have a multidimensional array(Ill call that original_array) and I would like to take the first array within original_array and set the values as keys in a new array. I also want to take the values of the second array in original_array and make them keys and then set the values of the third array in original_array as the values for those keys.
Here is an example of original_array:
Array (
[id] => Array (
[0] => 1
[1] => 3
)
[reward] => Array (
[0] => Movie
[1] => Trip
)
[cost] => Array (
[0] => 50
[1] => 200
)
)
Basically what I would like to do is look like this:
Array (
[1] => Array (
[Movie] => 50
)
[3] => Array (
[Trip] => 200
)
)
Is there a simple and elegant way to merge these like this?
I have spent hours trying to figure this out using array_merge, array_merge_recursive.. etc. And have search SO far and wide for a similar questions, but I haven't found anything that does what I am after.
I was able to correctly combine the 2nd and 3rd arrays in original_array with array_combine. But, I am at a loss as how to combine that result with the 1st array's values in original_array.
Thanks in advance to any help!
Well, the dirty way would be just use combine array functions like array_combine with the input:
$new_array = array_combine(
$array['id'], // parent keys
// combine chunked combined sub keys :p
array_chunk(array_combine($array['reward'], $array['cost']), 1, true)
);
There may be some incantation of array_*() merging functions that could produce what you're looking for, but it is far easier to just iterate over the original array's [id] sub-array and use its values to create new sub-array keys in a different output array.
// To hold your output
$output = array();
// Iterate the original array's [id] sub-array
foreach ($original['id'] as $idxkey => $newkey) {
// Add a sub-array using $newkey to the output array
$output[$newkey] = array(
// Using the index (not value), retrieve the corresponding reward
// value to use as the new array key
// and corresponding cost to use as the new subarray value
$original['reward'][$idxkey] => $original['cost'][$idxkey]
);
}
Here is a demonstration: https://3v4l.org/2pac3
This should work for you:
First you can get the keys for the main array into a separate variable with array_shift(), which will just remove the first element from your array, which is the array holding the keys.
Then use array_map() to loop through both of your subArrays and use reward as key with the cost values as value and return it in an array. At the end you just have to array_combine() your keys $keys with the new created array.
Code:
<?php
$keys = array_shift($arr);
$result = array_combine($keys, array_map(function($k, $v){
return [$k => $v];
}, $arr["reward"], $arr["cost"]));
print_r($result);
?>
You might wanna take a look at BaseArrayHelper from Yii 2.0 Framework.
Although this file is part of a framework it has only very few dependencies and you should be able to use just this file or parts of it in your code with small modifications.
An example for your use case can be found in the index() method.

Compare 2 arrays on single element in php

I have two arrays that look like this with many more results:
Array
(
[0] => Array
(
[comName] => John
[locID] => L152145
[locName] => Johns House
)
)
What i'd like to do is compare the results but only on the locName element...here is the code i'm working with thus far.
$searchcode = "a url to json results";
$simple = file_get_contents($searchcode);
$arr = json_decode($simple , true);
do this for each json file then
$result = array_intersect($arr, $anotherarr);
Ideally this would return the matching locNames from both arrays
Thanks for the help!
What you are a looking for is function array_uintersect:
$result = array_uintersect($arr, $anotherarr, function($a, $b) { return strcmp($a['locName'], $b['locName']); });
If each locName will appear only once, then I suggest you transform your array in an associative one in the form
Array
(
[Johns House] => Array
(
[comName] => John
[locID] => L152145
[locName] => Johns House
)
)
This way, you'll have access to every location name using array_keys, and will be able to pick the locations that are present in both arrays with a simple array_intersect on both array_keys.
The simplest way to do this is to iterate over the original array filling a new one (not really efficient if you're planning to manage 10000+ elements, but negligible in other case)
$assocA=array();
$assocB=array();
foreach($arr as $element) {
$assocA[$element['locName']]=$element;
}
foreach($anotherarr as $anotherelement) {
$assocB[$anotherelement['locName']]=$anotherelement;
}
$common_locations = array_intersect(array_keys($assocA), array_keys($assocB)); // will return all locnames present in both arrays.

Categories