PHP - Resort Array with a Key array [duplicate] - php

This question already has answers here:
Sorting a php array of arrays by custom order
(8 answers)
Closed 9 months ago.
Good day,
So I have the following array to start with that has items added to it. The order the items are added in the list have no specific sort to them to begin with other than the order they were originally added to the array in. For ease of reading, I put them in descending order to explain the result I am looking for. The values share a sub key of "tid" for this example.
Array
(
[0] => Array
(
[tid] => value_5
)
[1] => Array
(
[tid] => value_4
)
[2] => Array
(
[tid] => value_3
)
[3] => Array
(
[tid] => value_2
)
[4] => Array
(
[tid] => value_1
)
)
I now want to be able to feed a second array into a function, and have the array resorted so that the values supplied, which correlates to the "tid" of the field, are resorted to the front of the array in the order which they are given, and then leave the rest of the array in the order it currently is. For example, if I pass the following array as a sort key:
array("value_2", "value_3");
Then the value_2 and value_3 rows should become array key 0 and 1 respectively, but the rest of the array should stay in the same order like the following
Array
(
[0] => Array
(
[tid] => value_2
)
[1] => Array
(
[tid] => value_3
)
[2] => Array
(
[tid] => value_5
)
[3] => Array
(
[tid] => value_4
)
[4] => Array
(
[tid] => value_1
)
)
Alternatively, if a value that doesn't exist like value_9 is passed in the second array, we would just want to ignore that and skip past it.
I have explored a few options like a foreach and for loop and compared the values but its slow and doesn't really have recursion which seems like may be needed on this function.
As array sorting is a hot topic in PHP due to the myriad of ways to do so, I am looking to you guys for the best way to handle this problem. Thanks!

If I understood correctly your problem, here's a possible solution:
$firstArray = [
[ 'tid' => 'value_5' ],
[ 'tid' => 'value_4' ],
[ 'tid' => 'value_3' ],
[ 'tid' => 'value_2' ],
[ 'tid' => 'value_1' ],
];
$tidToAdd = [ 'value_2', 'value_3', 'value_9' ];
// The solution is below:
$intersect = array_intersect(array_column($firstArray, 'tid'), $tidToAdd);
$firstArrayFiltered = array_filter($firstArray, fn($elem) => !in_array($elem['tid'], $intersect));
$result = array_reduce($intersect, function($payload, $item) {
array_unshift($payload, ['tid' => $item]);
return $payload;
}, $firstArrayFiltered);

Related

php: converting an array of objects to pure array

following array is received at server side :
[{"id":"2","foo":"bar","children":[{"id":"4","foo":"baz","children":[{"id":"6"}]},{"id":"5"}]},{"id":"7"},{"id":"3"}]
is there any way to convert it to a nested array like this?
[
['id' => 2, 'foo' => 'bar', 'children' =>[
'id'=> 4, 'foo' => 'baz' ....
P.S: i find out that without using any function i will have desired code format on server side. maybe this is because of sending data as post request (using ajax) that convert data to an array then serialize it and send , then on server side i have a nice array the same as what i'm looking for.Im not sure it is ralated to php or laravel or jquery !?
Array
(
[0] => Array
(
[id] => 2
[children] => Array
(
[0] => Array
(
[id] => 4
[children] => Array
(
[0] => Array
(
[id] => 6
)
)
)
[1] => Array
(
[id] => 5
)
)
)
[1] => Array
(
[id] => 7
)
[2] => Array
(
[id] => 3
)
)
To get the array in PHP, Yes. Use json_decode().
To get the "nested array like this" in JSON, No. This is not how arrays in JSON are supposed to look. See the specification at json.org, it is really easy to understand.

Extract sub array resulting key=id and value=name in CakePHP

I have this nested array:
Array
(
[id] => 1
[name] => Group 1
[0] => Array
(
[id] => 1
[name] => Group 1
)
[1] => Array
(
[id] => 2
[name] => Group 2
)
[2] => Array
(
[id] => 7
[name] => Group 7
)
)
And I would like to extract sub arrays [0], [1], and [2] in one single array BUT following this format:
array(
[id] => [name]
)
In other words I would like to have this result:
Array
(
[1] => Group 1
[2] => Group 2
[7] => Group 7
)
*Note: I tried with Set::classicExtract($my_array['Group'], '{n}.name'); but I can't figure out how to get group.id as a key for my array. Any guidance will be appreciated.
This should work for you:
(Here I first array_filter() all values out, which don't have a numeric key. After this I simply array_combine() the id column with the name column which I get with array_column())
<?php
$result = array_filter($arr, function($k){
return is_numeric($k);
}, ARRAY_FILTER_USE_KEY);
$result = array_combine(array_column($result, "id"), array_column($result, "name"));
print_r($result);
?>
output:
Array ( [1] => Group 1 [2] => Group 2 [7] => Group 7 )
I figured out in case if someone else will be interested. Thanks a lot for the quick answers but I was looking on a solution using CakePHP.
Set::combine($my_array, '{n}.id', '{n}.name'); did the trick, cheers!

Sort Multidimensional Array in PHP based on date [duplicate]

This question already has answers here:
How can I sort arrays and data in PHP?
(14 answers)
Closed 8 years ago.
I have an array that looks something like this:
Array
(
[0] => Array
(
[id] => 4
[date] => 15.12.2014
[archived] => 0
)
[1] => Array
(
[id] => 3
[date] => 19.12.2014
[archived] => 0
)
[2] => Array
(
[id] => 6
[date] => 15.11.2014
[archived] => 0
)
)
What I would like to do is sort the items into high-to-low order in the first dimension based on the date value in the second dimension. I can use strtotime() on the [date] field and produce a unix timestamp (please note, these dates are in Australian format and not US. The server produces the correct timestamp).
I'm aware that I can use arsort() to arrange this array, but I'm not sure how to do it based on the value of a second dimension array key.
I need the array to look like this:
Array
(
[0] => Array
(
[id] => 3
[date] => 19.12.2014
[archived] => 0
)
[1] => Array
(
[id] => 4
[date] => 15.12.2014
[archived] => 0
)
[2] => Array
(
[id] => 6
[date] => 15.11.2014
[archived] => 0
)
)
How can I best achieve this in PHP?
I've tried various arrangements of the following to no avail:
arsort($items, strtotime(['date']))
You should use usort
In your case:
usort($items, function($a, $b) {
return strtotime($a['date']) - strtotime($b['date']);
});
Suppose that your $array is declared that way:
$my_array = array(
array(
'id'=>4,
'date'=>'19.12.2014',
'archived'=>0),
array(
'id'=>3,
'date'=>'15.12.2014',
'archived'=>0),
array(
'id'=>6,
'date'=>'15.11.2014',
'archived'=>0));
You can use usort function with a closure function as follows
usort($my_array, function($a, $b) {
return strtotime($a['date']) - strtotime($b['date']);
});
usort will sort your array "in place", means that no copy of array will be returned but original array is sorted.
Moreover, I've used strtotime to make order between dates as a starting dates are represent as strings and not in "real date" format.
Moreover keep in mind that
Note: This function assigns new keys to the elements in array. It will remove any existing keys that may have been assigned, rather than
just reordering the keys.
Execution test
Array
(
[0] => Array
(
[id] => 6
[date] => 15.11.2014
[archived] => 0
)
[1] => Array
(
[id] => 4
[date] => 15.12.2014
[archived] => 0
)
[2] => Array
(
[id] => 3
[date] => 19.12.2014
[archived] => 0
)
)

Complicated PHP transpose / pivot

I have the following array :
Array
(
[0] => Array
(
[Name] => first_data
[building] => A
[apt] => 16
)
[1] => Array
(
[Name] => first_data
[building] => B
[apt] => 16
)
[2] => Array
(
[Name] => second_data
[building] => A
[apt] => 17
)
[3] => Array
(
[Name] => second_data
[building] => B
[apt] => 18
)
and I need it to be returned as :
Array
(
[0] => Array
(
[Name] => first_data
[A] => 16
[B] => 16
)
[1] => Array
(
[Name] => second_data
[A] => 17
[B] => 18
)
Any ideas?
BTW the first array has hundreds of entries (not only first_data, but second and etc...) plus it has more than A and B.
Thanks in advance.
Not exactly what you want, but if you instead index the new array by the name, you can do this very easily. If the index number is some kind of ID, you can just create a field for it
foreach ( $oldarray as $index => $piece )
{
$newarray[$piece['Name']] = array($piece['building'] => $piece['apt'])
}
This will give you
Array
(
['first_data'] => Array
(
['A'] => 16,
['B'] => 16
)
['second_data'] => Array
(
['A'] => 17,
['B'] => 18
)
)
Since you have two entries with the same new, when you hit the 2nd loop, it will simply add the other building name. If you can work with this layout, then your solution is very easy, it will take more steps to do it exactly as you showed. If you absolutely have to do it the way you showed, you need extra code to loop through the new array, find the building name, add the key in the correct place, but this will be slower if you have a large amount of data.
In my opinion, the way I presented it is a far easier way to look around the array too. If you wanted to know the apt value for A in "second_data" you can just do
$newarray['second_data']['A']
with your array layout, it would require a loop to search the array for "second_data" because you have no idea where it is.

Mustache not iterating over array

I don't know what is going on (maybe it because it is the 12th consecutive hour working).
I always used this notation but now it just doesn't work (I already checked several time that the data is passed to this template I'm talking about).
Data is not iterated and the result is empty.
Mustache code:
{{#ad}}
setInput("{{key}}", "{{value}}");
{{/ad}}
I tried also:
{{#ad}}
setInput("{{key}}", "{{value}}");
{{/ad}}
The data passed is the following:
Array
(
[ad] => Array
(
[0] => Array
(
[key] => id
[value] => 1
)
[1] => Array
(
[key] => created_on
[value] => 1371464401
)
[2] => Array
(
[key] => updated_on
[value] =>
)
[3] => Array
(
[key] => dealer_id
[value] => 1
)
)
)
Solved: be careful to not pass hashes instead of "plain" arrays!! Even if it seemed to be a common array because of the indexing (0 => "a", 1 => "b") it was actually an hash! So just return the malicious data within an array_values($data) to fix it!

Categories