My array has an array for each field (i.e date, name, etc.). How do I sort the array by date? Should I create another array? Can I use sort or unsort here. If yes, how? Here is my array:
Array
(
[date] => Array
(
[0] => 03/11/2019
[1] => 03/19/2019
[2] => 03/15/2019
[3] => 12/15/2018
)
[name] => Array
(
[0] => Lowa
[1] => Stephanie
[2] => Allan
[3] => Joffer
)
[number] => Array
(
[0] => 178989898
[1] => 111111111
[2] => 222222222
[3] => 333333333
)
[unit] => Array
(
[0] => HR
[1] => VPP
[2] =>
[3] => OAT
)
[department] => Array
(
[0] => Chemistry
[1] => IT
[2] => Lab
[3] => Contractor
)
)
At the end, my first element will be:
03/19/2019 Stephanie 111111111 VPP IT
I think your data can be better organized:
$newArr = Array
(
[0] => Array
(
[date] => 03/11/2019
[name] => Lowa
[number] => 178989898
[unit] => HR
[department] => Chemistry
)
[1] => Array
(
[date] => 03/19/2019
[name] => Stephanie
[number] => 111111111
[unit] => VPP
[department] => IT
)
[2] => Array
(
[date] => 03/15/2019
[name] => Allan
[number] => 222222222
[unit] =>
[department] => Lab
)
[3] => Array
(
[date] => 12/15/2018
[name] => Joffer
[number] => 333333333
[unit] => OAT
[department] => Contractor
)
);
Then, you can simply sort it by:
function cmp($a, $b) {
if ($a["date"] == $b["date"]) return 0;
return ($a["date"] < $b["date"]) ? -1 : 1;
}
usort($newArr, "cmp");
Please be warned that dates in the format "Month/Day/Year" ar not alphabetically sortable.
You definitively should use a Year/Month/Day format for your dates, or write a more specific cmp() function...
UPDATE: To answer OP's question in comment: just reverse $row and 'field' order:
for ($row = 0; $row < count($date); $row++) {
$newArr[$row]['date'] = $date[$row];
$newArr[$row]['name'] = $name[$row];
...
}
First save the keys of your array - then by using array_value convert to integer keys so you can use the ... operator.
Then you can use array_filter with null function to re-organize your array. Next step will be to get the keys back using array_map and array_combine.
Last step - sort by "data" with usort
Consider the following example:
$arr = ["date" => ["3", "7", "5"], "name" => ["aa", "bb", "cc"]]; // this can have a lot more sub-array inside
$keys = array_keys($arr); // extract the keys for later use
$res = array_map(null, ...array_values($arr)); // transposed the array
$res = array_map(function ($e) use ($keys) {return array_combine($keys, $e);}, $res); // return the keys to the transposed array
usort($res, function ($a, $b) {return strcmp($a['date'], $b['date']);} ); // sort all by "date"
Reference:
array-keys, array-filter, array-map, usort, array-values
Notice #MarcoS post comment regarding the comparing dates
Related
I have a big array as $orderArr:
$orderArr = array("IZQ", "AOH", "VNP", "ICW", "IOQ", "BXP", "SHH", "EAY", "ZAF", "CUW");
which looks like
Array ( [0] => IZQ [1] => AOH [2] => VNP [3] => ICW [4] => IOQ [5] => BXP [6] => SHH [7] => EAY [8] => ZAF [9] => CUW )
and I have two small arrays as $subArr1 and $subArr2:
$subArr1 = array("VNP", "BXP", "ICW", "IZQ");
$subArr2 = array("ZAF", "IZQ", "AOH");
looks like
Array ( [0] => VNP [1] => BXP [2] => ICW [3] => IZQ )
Array ( [0] => ZAF [1] => IZQ [2] => AOH )
Both small arrays (sub array) own elements belong to the big array.
I want to sort two small arrays according to the order of big array, as following:
Array ( [0] => IZQ [1] => VNP [2] => ICW [3] => BXP )
Array ( [0] => IZQ [1] => AOH [2] => ZAF )
I am looking for the simplest codes to do it in php. Any suggestions are welcome.
Probably the simplest would be to compute the intersection and it will return in the order of the first array:
$subArr1 = array_intersect($orderArr, $subArr1);
That will return with the keys of the first array; if you want to reindex instead:
$subArr1 = array_values(array_intersect($orderArr, $subArr1));
You could use usort to sort based on array position:
usort($subArr1, function ($a, $b) use ($orderArr) {
return (array_search($a, $orderArr) < array_search($b, $orderArr)) ? -1 : 1;
});
var_dump($subArr1);
I have the following multi dimensional PHP array. What I'm trying to do is return only the value which occurs in all of the arrays.
So in the array below the only value which occurs in every array is "2018-02-22", so I want to create a new array with only this value.
I feel like it can't be too difficult, but I just can't get my head around how to do this. If any one can help it would be much appreciated!
Array
(
[0] => Array
(
[0] => 2018-02-22
)
[1] => Array
(
[0] => 2018-02-22
[1] => 2018-02-21
[2] => 2018-02-20
[3] => 2018-02-16
[4] => 2018-02-14
)
[2] => Array
(
[0] => 2018-02-20
[1] => 2018-02-19
[2] => 2018-02-21
[3] => 2018-02-22
[4] => 2018-02-14
)
[3] => Array
(
[0] => 2018-02-22
[1] => 2018-02-12
[2] => 2018-02-01
)
)
So to clarify the output I'm aiming for is:
Array
(
[0] => 2018-02-22
)
You can do it by array_intersect, to get common value 2018-02-22.
<?php
$dates = [
["2018-02-22","2018-02-23"],
["2018-02-22","2018-02-24"],
["2018-02-22","2018-02-25"],
];
$common = array_shift($dates);
foreach($dates as $key=>$date){
$common = array_intersect($common, $date);
}
print_r($common);
?>
Live Demo
Output is :
Array (
[0] => 2018-02-22
)
Help me pls combine array values.
I have the same array:
In my case i should save customers name like a key.
Array
(
[Test Name] => Array
(
[0] => Array
(
[name] =>
banana
[id] =>
45002
[quantity] =>
10
)
[1] => Array
(
[name] =>
banana
[id] =>
45002
[quantity] =>
20
)
[3] => Array
(
[name] =>
apple
[id] =>
23402
[qua] =>
1
)
[5] => Array
(
[name] =>
cherry
[id] =>
40017
[qua] =>
7
)
How to get something like this:
Array
(
[Test Name] => Array
(
[0] => Array
(
[name] =>
banana
[id] =>
45002
[quantity] =>
30 // summ quantity but unique name and id
)
[1] => Array
(
[name] =>
apple
[id] =>
23402
[qua] =>
1
)
[2] => Array
(
[name] =>
cherry
[id] =>
40017
[qua] =>
7
)
In my case i should save customers name like a key.
Then i will upload this on a table.
You can use array_map and array_reduce to accomplish it:
$results = array_map(function ($result) {
return array_reduce($result, function ($carry, $item) {
if (isset($carry[$item['id']])) {
$carry[$item['id']]['quantity'] += $item['quantity'];
} else {
$carry[$item['id']] = $item;
}
return $carry;
}, array());
}, $results);
From the documentation:
array_map() returns an array containing all the elements of array1 after applying the callback function to each one.
array_reduce() applies iteratively the callback function to the elements of the array, so as to reduce the array to a single value.
In our case the callback given to the array_reduce function returns a final array which contains unique items by id.
I have a rather annoying array structure to work with and I need to sort it by any arbitrary key combination. 2 records are displayed below but multiple records with or without the same structure will be present when sorting is actioned.
Here are two records.
Array(
[0] => Array
(
[cid] => 1
[title] => Mr
[first_name] => Abet
[last_name] => Simbad
[emails] => Array
(
[374] => Array
(
[eid] => 374
[name] => ski lodge
[email] => simbad#skifree.com
)
[373] => Array
(
[eid] => 373
[name] => work
[email] => simbad#work.com
)
[375] => Array
(
[eid] => 375
[name] => personal
[email] => simbad#gmail.com
)
)
)
[1] => Array
(
[cid] => 2
[title] => Mrs
[first_name] => Angie
[last_name] => Stokes
[emails] => Array
(
[590] => Array
(
[eid] => 590
[name] => work
[email] => angie#gmail.com
)
)
)
So if I wanted to sort by email in ascending order in the emails array, how can I get the second complete record to come first in the result array? angie#gmail.com comes before simbad#....
Also Some records will not contain an emails array. They would be last in the result set.
Any help would be much appreciated.
The array shown is a cut down version but I have addresses, notes, phones and websites in the same annoying structure. Ideally I could sort with something like
$sort = array('emails','email')
$data = sort_data_func('ASC',$sort,$data);
But anything steps in the right direction will help. :)
Here's some code I have so far
$sort = array('emails','email');
foreach($contacts as $ckey => $c){
if(is_array($c[$sort[0]])){
foreach($c[$sort[0]] as $key1 => $sort0){
if($sort0[$sort[1]]!=''){
$res[$sort[0]][$ckey][$sort[1]][] = $sort0[$sort[1]];
}
}
}
}
print_r($res);
Which produces:
Array
(
[emails] => Array
(
[0] => Array
(
[0] => simbad#skifree.com
[1] => simbad#work.com
[2] => simbad#gmail.com
)
[1] => Array
(
[0] => angie#gmail.com
)
)
)
But I have no idea where to go from here.
EDIT
OK I have the records in the currect order now but how can I keep the initial record ID in the resulting array?
Here's what I'm using.
$direction=='ASC'
function cmp_asc($a, $b){
$key = current(array_keys($a));
sort($a[$key]);
$a[$key] = current($a[$key]);
sort($b[$key]);
$b[$key] = current($b[$key]);
if ($a == $b) {
return 0;
}
return ($a < $b) ? -1 : 1;
}
function cmp_desc($a, $b){
$key = current(array_keys($a));
asort($a[$key]);
$a[$key] = current($a[$key]);
asort($b[$key]);
$b[$key] = current($b[$key]);
if ($a == $b) {
return 0;
}
return ($a < $b) ? -1 : 1;
}
if($direction=='ASC'){
usort($res[$sort[0]], 'cmp_asc');
}else{
usort($res[$sort[0]], 'cmp_desc');
}
In
Array
(
[emails] => Array
(
[0] => Array
(
[email] => Array
(
[0] => simbad#skifree.com
[1] => simbad#work.com
[2] => simbad#gmail.com
)
)
[1] => Array
(
[email] => Array
(
[0] => angie#gmail.com
)
)
)
)
Out
Array
(
[emails] => Array
(
[0] => Array
(
[email] => Array
(
[0] => angie#gmnail.com
)
)
[1] => Array
(
[email] => Array
(
[0] => simbad#skifree.com
[1] => simbad#work.com
[2] => simbad#gmail.com
)
)
)
)
One of the usort functions, combined with a self-written comparison function that detects the order in which two elements should be sorted, should do the trick.
I want to merge two arrays into one array as follows,
Array1:
Array
(
[0] => Array
(
[id] => 3
[sku] => KOG456
[cart_id] => 2
[name] => Young Money
[slug] => young-money
[route_id] => 47
[description] =>
This is test song
[excerpt] =>
[saleprice] => 90.00
[related_products] =>
[images] => {"1c6b0883fc94c5f644497ec488cdf8cb":{"filename":"1c6b0883fc94c5f644497ec488cdf8cb.jpg","alt":"Test","caption":"","primary":true}}
[seo_title] =>
[meta] =>
[enabled] => 1
)
)
Array2:
Array
(
[0] => Array
(
[filename] => Beethovens_Symphony_No._9_(Scherzo).wma
[title] => Young Money
[size] => 599.26
)
)
Expected array result is:
Array
(
[0] => Array
(
[id] => 3
[sku] => KOG456
[cart_id] => 2
[name] => Young Money
[slug] => young-money
[route_id] => 47
[description] =>
This is test song
[excerpt] =>
[saleprice] => 90.00
[related_products] =>
[images] => {"1c6b0883fc94c5f644497ec488cdf8cb":{"filename":"1c6b0883fc94c5f644497ec488cdf8cb.jpg","alt":"Test","caption":"","primary":true}}
[seo_title] =>
[meta] =>
[enabled] => 1
[filename] => Beethovens_Symphony_No._9_(Scherzo).wma
[title] => Young Money
[size] => 599.26
)
)
How to merge these array elements into one array element ?
foreach ($origArray as $key => &$subArray)
$subArray += $arrayToBeAdded[$key];
Where $origArray is your array which is to be merged into and $arrayToBeAdded the array you merge into.
User array_merge_recursive():
$final = array_merge_recursive($array1, $array2);
Try this little known overload of the + operator for arrays:
$result = $array1[0] + $array2[0]
Use function array_merge($array1[0], $array2[0]) . Following is the example for the same
$array1 = array(0=>array('1'=>1,'2'=>2,'3'=>3));
$array2 = array(0=>array('4'=>4,'5'=>5,'6'=>6));
$result[0] = array_merge($array1[0],$array2[0]);
echo '<pre>';
print_r($result);
Since you have unique keys, you could use something as simple as the + operator (union)...
For example:
$arr1 = [1=>'testing',2=>'stack',3=>'overflow'];
$arr2 = [4=>'something',5=>'else',6=>'here'];
$arr3 = $arr1 + $arr2;
print_r($arr3);
Results:
Array ( [1] => testing [2] => stack [3] => overflow [4] => something [5] => else [6] => here )
For this php has multiple functions. You can use $arrays = array_combine($array1, $array2);.
PHP.net - array_combine
Hope it helped!