computation on array-search in php - php

I have a multi-D array like so:
array ( 'JD'=>2457002.50, 67.618536),
array ( 'JD'=>2457003.50, 67.619705),
array ( 'JD'=>2457004.50, 67.620938)....
I have a value say:
$MyJD = 2457003.9553;
I would like to find the value in the array, and if not, match the closest number to the array in question and return the the next index (which i'm assuming is [1])
I was thinking to do an array_search, but it's not going to find the exact number, I want the closest number to $MyValue?

This won't return the index but will return the proper array:
array_multisort(array_map(function($v) use($MyJD) {
return abs($v['JD'] - $MyJD);
}, $array), $array);
$result = reset($array);
Calculate the difference between each JD value and $MyJD
Sort on the difference (sorting the original) and get the lowest (first) one
Alternately, you could combine using the difference as the key and then sort on the keys:
$array = array_combine(array_map(function($v) use($MyJD) {
return abs($v['JD'] - $MyJD);
}, $array), $array);
ksort($array);
$result = reset($array);
Maybe someone will post a good array_reduce answer.

Do bucle put new array with key difference between
In this way you will have array ordered by difference
In each iteration
$myarray[myvalue - yourvalueinbucle] if -1 this key then ×-1 and how value your enter iterator of bucle, then your value for this key = your line multiarrayvalue in for each iterator

Related

PHP removing a specific array from a multidimensional array

I have a multidimensional array in PHP where I need to remove one array based on the value of an item in one of the arrays:
Example Array
array(
"0"=>array("0"=>"joe", "1"=>"2018-07-18 09:00:00"),
"1"=>array("0"=>"tom", "1"=>"2018-07-17 09:00:00"),
"2"=>array("0"=>"joe", "1"=>"2018-07-14 09:00:00")
)
I know that I want to remove the array that contains joe in key 0, but I only want to remove the array that contains joe with the most current date in key1. The following output is what I'm trying to accomplish:
array(
"0"=>array("0"=>"tom", "1"=>"2018-07-17 09:00:00"),
"1"=>array("0"=>"joe", "1"=>"2018-07-14 09:00:00")
)
Is there a simple way to do this in PHP aside from looping through each array?
Here is a non looping method that uses array_intersect and array_column to find the "Joe's" and then deletes the maximum array_key since I first sort the array on dates.
usort($arr, function($a, $b) {
return $a[1] <=> $b[1];
}); // This returns the array sorted by date
// Array_column grabs all the names in the array to a single array.
// Array_intersect matches it to the name "Joe" and returns the names and keys of "Joe"
$joes = array_intersect(array_column($arr, 0), ["joe"]);
// Array_keys grabs the keys from the array as values
// Max finds the maximum value (key)
$current = max(array_keys($joes));
unset($arr[$current]);
var_dump($arr);
https://3v4l.org/mah6K
Edit forgot to add the array_values() if you want to reset the keys in the array.
Just add $arr = array_values($arr); after the unset.
I would go about it like this:
<?php
$foo = array(
"0"=>array("0"=>"joe", "1"=>"2018-07-18 09:00:00"),
"1"=>array("0"=>"tom", "1"=>"2018-07-17 09:00:00"),
"2"=>array("0"=>"joe", "1"=>"2018-07-14 09:00:00")
);
$tmp = [];
foreach($foo as $k => $v) {
if ($v[0] === 'joe') {
$tmp[$v[1]] = $k;
}
}
if (!empty($tmp)) {
sort($tmp); //think that is sane with date format?
unset($foo[reset($tmp)]);
}
var_dump($foo);
Not sure if you don't want to loop on principal or what... I tend to go for readability. Find all occurrences of joe. Sort on date. Remove the most recent by key.

How to get key of an associative array by searching for offset value?

Using this as an example and being aware of key,
$arr = array(
'product1'=>array('color'=>'blue','size'=>'medium'),
'product2'=>array('color'=>'green','size'=>'large'),
'product3'=>array('color'=>'yellow','size'=>'small'),
);
Is there a method for getting any key in multidimensional array by its incremented value?
For example, I'd like to get the key of the third array value in $arr above. $arr[2] would return the value (an array containing yellow/small).
Is there a way to leverage the key function to get any key by its numeric iterator, rather than the key from the "current position"?
Or, is there another built-in function that I am obviously overlooking which would return the key of $arr[2] instead of it's value?
echo getkey($arr[2]);
# returns product3
Just use array_keys function :
$arr = array(
'product1'=>array('color'=>'blue','size'=>'medium'),
'product2'=>array('color'=>'green','size'=>'large'),
'product3'=>array('color'=>'yellow','size'=>'small'),
);
$keys = array_keys($arr);
echo $keys[2];
// shorter version
echo array_keys($arr)[2];
More infos : http://php.net/manual/en/function.array-keys.php
It doesn't seem logical/efficient to generate a new/full array of keys just to select one from it. The other answers are "working too hard".
array_slice() specifically extracts portions of an array based on position rather than key name. This makes it the perfect function for this case.
Better practice would be to only slice away the subarray that you want, then call for its key, like this:
Code: (Demo)
$arr = array(
'product1'=>array('color'=>'blue','size'=>'medium'),
'product2'=>array('color'=>'green','size'=>'large'),
'product3'=>array('color'=>'yellow','size'=>'small'),
);
$key=2;
echo key(array_slice($arr,$key,1)); // [input],[0-indexed position],[number of subarrays]
Output:
product3
You can use array_keys() function:
function getKey($arr, $i) {
if (empty($arr[array_keys($arr)[$i]])) {
return null;
}
// array_keys($arr)[$i] returns original array's key at i position
// if i = 2, array_keys($arr)[$i] = 'product3'
return array_keys($arr)[$i];
}
// echo getKey($arr, 2);
// returns product3

Safety net for array_slice

I read that array_merge will return NULL if you try to merge an empty array and any other array. That's not what I hope to do. I am trying to merge an array with a new array that is actually a slice of another array. ($i is an integer).
$forgotten = array_slice($matches, $i) ;
$leftOvers = array_merge($leftOvers, $forgotten);
The question is, what does array_slice return when the index is not found? If it can return null, should I do something like this:
$forgotten = array_slice($matches, $i) || array();
Also, is there any difference between using array_merge like this, and pushing $forgotten into leftOvers?
if you use array_merge over an empty array and another array it will return an array composed with the elements of the not empty array. If you try to merge two empty arrays it will return an empty array.
array_slice($matches, $i)
array_slice returns an array with all the elements of $matches with index greater or equal $i, if there are no such elements it will return an empty array.
Using array_push:
array_push($leftOvers, $forgotten)
$result will enqueue an array as a value the end of $leftOvers.
Always try to read the php man when you use a new php function, also you could get all these answers just trying to execute the functions in a test.php file.

Swap my element's order to be the first in an array

Let's say I have an array like so:
array(
[0]=>1
[1]=>3
[3]=>5
[15]=>6
);
Arbitrarily I want array[15] to be the first:
array(
[15]=>6
[0]=>1
[1]=>3
[3]=>5
);
What is the fastest and most painless way to do this?
Here are the things I've tried:
array_unshift - Unfortunately, my keys are numeric and I need to keep the order (sort of like uasort) this messes up the keys.
uasort - seems too much overhead - the reason I want to make my element the first in my array is to specifically avoid uasort! (Swapping elements on the fly instead of sorting when I need them)
Assuming you know the key of the element you want to shift, and that element could be in any position in the array (not necessarily the last element):
$shift_key = 15;
$shift = array($shift_key => $arr[$shift_key]);
$arr = $shift + $arr;
See demo
Updated - unset() not necessary. Pointed out by #FuzzyTree
You can try this using a slice and a union operator:
// get last element (preserving keys)
$last = array_slice($array, -1, 1, true);
// put it back with union operator
$array = $last + $array;
Update: as mentioned below, this answer takes the last key and puts it at the front. If you want to arbitrarily move any element to the front:
$array = array($your_desired_key => $array[$your_desired_key]) + $array;
Union operators take from the right and add to the left (so the original value gets overwritten).
If #15 is always last you can do
$last = array_pop($array); //remove from end
array_unshift($last); //push on front
To reorder the keys for sorting simply add
$array = array_values($array); //reindex array
#Edit - if we don't assume its always last then I would go with ( if we always know wwhat the key is, then most likely we will know its position or it's not a numerically indexed array but an associative one with numeric keys, as op did state "arbitrarily" so one has to assume the structure of the array is known before hand. )
I also dont see the need to reindex them as the op stated that it was to avoid sorting. So why would you then sort?
$item = $array[15];
unset($array[15]); //....etc.

How to get the last n items in a PHP array as another array?

How to I get an array of the last n items of another array in PHP?
$n is equal to the number of items you want off the end.
$arr = array_slice($old_arr, -$n);
You can use array_slice:
$arr = array_slice($old_arr, -$n, $n, true);
If the array indices are meaningful to you, remember that array_slice will reset and reorder the numeric array indices. You need the preserve_keys flag (4th parameter) set to true to avoid this.

Categories