I need to reorder multidimensional array by Region Name.
But my multiarray is actually indexed by REGION_ID (first key) for semplicity like:
$array = array(
1 => array( // 1 is REGION_ID
"Value" => "Val-1",
"Children" => array(
...
)
),
2 => array( // 2 is REGION_ID
"Value" => "Val-2",
"Children" => array(
...
)
),
3 => array( // 3 is REGION_ID
"Value" => "Val-3",
"Children" => array(
...
)
),
4 => array( // 4 is REGION_ID
"Value" => "Val-4",
"Children" => array(
...
)
),
...
);
foreach ( $array as $region_id => $sub_array ) {
var_dump($region_id);
}
Where my table REGION is:
ID | Name
--------------
1 | Emilia
--------------
2 | Calabria
--------------
3 | Veneto
--------------
4 | Puglia
--------------
...
I'd like, so, to reorder my $array by Name of my table:
Calabria, then, Emilia, Puglia, Veneto... so my $array has to be:
$array = array(
2 => array(
"Value" => "Val-2",
"Children" => array(
...
)
),
1 => array(
"Value" => "Val-1",
"Children" => array(
...
)
),
4 => array(
"Value" => "Val-4",
"Children" => array(
...
)
),
3 => array(
"Value" => "Val-3",
"Children" => array(
...
)
),
...
);
I don't know how to sort using my logic...
assign the correct sorted array from database to $sorting
$sorting = ...[some function to retrive a sorted array from the database in the desired order]
for example "SELECT * FROM REGION ORDER BY Name"
ERRATA:
if you can't add the "ORDER BY" to sql query, just get the values and use usort (http://php.net/manual/en/function.usort.php) function to have the $sorting array in the correct order.
so, you should have something like (eqivalent):
$sorting = [
['ID' => 2, 'Name' => 'Calabria'],
['ID' => 1, 'Name' => 'Emilia'],
['ID' => 4, 'Name' => 'Puglia'],
['ID' => 3, 'Name' => 'Veneto']
];
or var_dump($sorting)
array (size=4)
0 =>
array (size=2)
'ID' => int 2
'Name' => string 'Calabria' (length=8)
1 =>
array (size=2)
'ID' => int 1
'Name' => string 'Emilia' (length=6)
2 =>
array (size=2)
'ID' => int 4
'Name' => string 'Puglia' (length=6)
3 =>
array (size=2)
'ID' => int 3
'Name' => string 'Veneto' (length=6)
now run the following loop:
$sorted_array = [];
foreach ($sorting as $sort_element) {
$sorted_array[] = $array[$sort_element['ID']];
}
the $sorted_array will have the required sort order
array (size=4)
0 =>
array (size=2)
'Value' => string 'Val-2' (length=5)
'Children' => ...
1 =>
array (size=2)
'Value' => string 'Val-1' (length=5)
'Children' => ...
2 =>
array (size=2)
'Value' => string 'Val-4' (length=5)
'Children' => ...
3 =>
array (size=2)
'Value' => string 'Val-3' (length=5)
'Children' => ...
<?php
$array = array(
1 => array(
"Value" => "Val-1",
"Children" => array(
)
),
2 => array(
"Value" => "Val-2",
"Children" => array(
)
),
3 => array(
"Value" => "Val-3",
"Children" => array(
)
),
4 => array(
"Value" => "Val-4",
"Children" => array(
)
),
);
$region = array(1 => 'Emilia', 2 => 'Calabria', 3 => 'Veneto', 4 => 'Puglia');
asort($region);
$new_array = [];
foreach ($region as $key => $value) {
$new_array[ $key ] = $array[ $key ];
}
print_r($new_array);
You can see this working here : http://tpcg.io/K23FfH
Related
What I have:
array(
[
'id' => 12, 'group' => 'abc', 'name' => 'Lorem',
],
[
'id' => 12, 'group' => 'def', 'name' => 'Ipsum',
],
[
'id' => 34, 'group' => 'ghi', 'name' => 'Dolor',
],
[
'id' => 34, 'group' => 'jkl', 'name' => 'Sit',
],
[
'id' => 34, 'group' => 'mno', 'name' => 'Amet',
],
);
What I want:
array (size=2)
12 =>
array (size=2)
'abc' =>
array (size=3)
'id' => int 12
'group' => string 'abc' (length=3)
'name' => string 'Lorem' (length=5)
'def' =>
array (size=3)
'id' => int 12
'group' => string 'def' (length=3)
'name' => string 'Ipsum' (length=5)
34 =>
array (size=3)
'ghi' =>
array (size=3)
'id' => int 34
'group' => string 'ghi' (length=3)
'name' => string 'Dolor' (length=5)
'jkl' =>
array (size=3)
'id' => int 34
'group' => string 'jkl' (length=3)
'name' => string 'Sit' (length=3)
'mno' =>
array (size=3)
'id' => int 34
'group' => string 'mno' (length=3)
'name' => string 'Amet' (length=4)
What I tried:
The obvious:
$sorted = array();
foreach ($products as $product) {
$sorted[$product['id']][$product['group']] = $product;
}
$products = $sorted;
unset($sorted);
But then, in an effort to avoid foreach() loops, and with help of #atomrc's answer to How to group subarrays by a column value?, I came up with this:
$sorted = array_reduce($products, function ($accumulator, $element) {
$accumulator[$element['id']][] = $element;
return $accumulator;
}, []);
array_walk($sorted, function(&$item) {
$item = array_reduce($item, function ($accumulator, $element) {
$accumulator[$element['group']] = $element;
return $accumulator;
}, []);
});
So while the above looks cool and all, it's also much bigger and seemingly more complex than that foreach. This is probably because my experience with array_reduce() is limited. Is there a way to have the array grouped in one go? For example, in the first array_reduce() call.
Personally I don't see an issue with the foreach solution, but if you want to use array_reduce you can simply use the inner code from the foreach loop:
$grouped = array_reduce($products, function ($c, $v) {
$c[$v['id']][$v['group']] = $v;
return $c;
}, []);
print_r($grouped);
The output of this code is the same as your foreach loop.
Note that this (and your foreach loop) won't deal correctly with the situation where there is more than one array with the same id and group values. For example, if we extend $products:
$products[] = [
'id' => 34, 'group' => 'jkl', 'name' => 'Consectetur',
];
Then the first jkl group value gets overwritten by the second. To deal with this you need to make each group an array e.g.
$grouped = array_reduce($products, function ($c, $v) {
$c[$v['id']][$v['group']][] = $v;
return $c;
}, []);
print_r($grouped);
In this case the jkl group then looks like:
[jkl] => Array
(
[0] => Array
(
[id] => 34
[group] => jkl
[name] => Sit
)
[1] => Array
(
[id] => 34
[group] => jkl
[name] => Consectetur
)
)
Demo on 3v4l.org
This question already has answers here:
Merge row data from multiple arrays
(6 answers)
Closed 4 months ago.
This is my array:
array
0 =>
array
'id' => int 220950
'order_reference' => string '600125479'
1 =>
array
'id' => int 220985
'order_reference' => string '498638'
and this my another array
array
0 =>
array
'entity_id' => 1
'order_status' => 'test'
1 =>
array
'entity_id' => 2
'order_status' => 'test2'
and my goal is to achieve this:
array
0 =>
array
'id' => int 220950
'order_reference' => string '600125479'
'entity_id' => 1
'order_status' => 'test'
1 =>
array
'id' => int 220985
'order_reference' => string '498638'
'entity_id' => 2
'order_status' => 'test2'
with array_merge I managed to get this(NOT my desired goal) and this all I found on stackoverflow and other forums:
array
0 =>
array
'id' => int 220950
'order_reference' => string '600125479'
1 =>
array
'id' => int 220985
'order_reference' => string '498638'
array
2 =>
array
'entity_id' => 1
'order_status' => 'test'
3 =>
array
'entity_id' => 2
'order_status' => 'test2'
Any ideas or suggestions are welcomed :) thank you
Using a foreach I can add the keys values, but I am looking for a more cleanest way :)
Here's the answer to your question using array_map and array_merge_recursive.
<?php
$array1 = array(
[
"id" => 220950,
"order_reference" => "600125479"
],
[
"id" => 220985,
"order_reference" => "498638"
]
);
$array2 = array(
[
"entity_id" => 1,
"order_status" => "test"
],
[
"entity_id" => 2,
"order_status" => "test"
]
);
$results = array();
array_map(function($array1, $array2) use (&$results) {
$results[] = array_merge_recursive($array1, $array2);
}, $array1, $array2);
var_dump($results);
This will output:
array (size=2)
0 =>
array (size=4)
'id' => int 220950
'order_reference' => string '600125479' (length=9)
'entity_id' => int 1
'order_status' => string 'test' (length=4)
1 =>
array (size=4)
'id' => int 220985
'order_reference' => string '498638' (length=6)
'entity_id' => int 2
'order_status' => string 'test' (length=4)
With the caveat that your arrays don't have a joint value to compare against so you need to make sure that the keys always line up, I think a loop like this will do the trick:
for ($i = 0; $i < count($array1); $i++)
{
$new_array[] = array_merge($array1[$i], $array2[$i]);
}
Edit: You can also use array_map() but it doesn't offer any performance advantages AFAIK, and is overall less readable.
$new_array = array_map(function($a1_v, $a2_v) { return array_merge($a1_v, $a2_v); }, $a1, $a2);
Use array_merge with array_map
$array1 = array(
[
"id" => 220950,
"order_reference" => "600125479"
],
[
"id" => 220985,
"order_reference" => "498638"
]
);
$array2 = array(
[
"entity_id" => 1,
"order_status" => "test"
],
[
"entity_id" => 2,
"order_status" => "test2"
]
);
$result = array_map("array_merge",$array1,$array2);
print_r($result);
Output
Array
(
[0] => Array
(
[id] => 220950
[order_reference] => 600125479
[entity_id] => 1
[order_status] => test
)
[1] => Array
(
[id] => 220985
[order_reference] => 498638
[entity_id] => 2
[order_status] => test2
)
)
Working example
My Code was :
$data = array();
foreach ($table as $key => $var) {
$data[] = ['id' => $var->id, 'value' => $var->designation];
}
My Data array should be like this
array (
0 => array (
'id' => 27,
'value' => 'laravel',
),
1 => array (
'id' => 1,
'value' => 'laravel tester',
),
2 => array (
'id' => 22,
'value' => 'laravel developer',
),
3 => array (
'id' => 23,
'value' => 'laravel casts',
),
4 => array (
'id' => 24,
'value' => 'laravel developer',
),
)
I need only one value i tried all the php core library function output:
array (
0 =>
array (
'id' => 27,
'value' => 'laravel',
),
1 => array (
'id' => 1,
'value' => 'laravel tester',
),
2 => array (
'id' => 23,
'value' => 'laravel casts',
),
3 => array (
'id' => 24,
'value' => 'laravel developer',
),
)
Based on the name only i need to remove duplicate bacause in my search bar it shows repeated mode.
You can use array_unique, wich saves indexes, and get the result by array_intersect_key
$temp = array_unique(array_column($arr, 'value'));
$res = array_intersect_key($arr, $temp);
print_r($res);
So, I am sending data from View to Controller and need to save all (multiple) data in DB.
in view I am using category[], status_number[] and name[] to collect data, then I got this:
[
'category' => [
(int) 0 => 'c',
(int) 1 => 'c1',
(int) 2 => 'c2'
],
'status_number' => [
(int) 0 => 'sn',
(int) 1 => 'sn1',
(int) 2 => 'sn2'
],
'name' => [
(int) 0 => 'n',
(int) 1 => 'n1',
(int) 2 => 'n2'
]
]
now I need to transform (combine) this array so that I can store it to DB in this structure
[
'(int) 0' => [
category => 'c',
status_number => 'sn',
name => 'n'
],
'(int) 1' => [
category => 'c1',
status_number => 'sn1',
name => 'n1'
],
'(int) 2' => [
category => 'c2',
status_number => 'sn2',
name => 'n2'
]
]
You can try something like that:
<?php
$array = [
'category' => [
'c',
'c1',
'c2'
],
'status_number' => [
'sn',
'sn1',
'sn2'
],
'name' => [
'n',
'n1',
'n2'
]
];
$result = [];
array_walk($array, function($data, $key) use (&$result){
foreach($data as $numericKey => $value) {
$result[$numericKey][$key] = $value;
}
});
print_r($result);
As the result it gives:
Array
(
[0] => Array
(
[category] => c
[status_number] => sn
[name] => n
)
[1] => Array
(
[category] => c1
[status_number] => sn1
[name] => n1
)
[2] => Array
(
[category] => c2
[status_number] => sn2
[name] => n2
)
)
I have this array, which is already sorted by 'name' ASC.
array
0 =>
array
'id' => '4'
'name' => 'iPad'
'games' => 5
1 =>
array
'id' => '5'
'name' => 'iPhone'
'games' => 5
2 =>
array
'id' => '6'
'name' => 'Nintendo DS'
'games' => 5
3 =>
array
'id' => '1'
'name' => 'Playstation 2'
'games' => 2
4 =>
array
'id' => '7'
'name' => 'Playstation 3'
'games' => 2
5 =>
array
'id' => '7'
'name' => 'Xbox 360'
'games' => 1
I wanted to be sorted by the value of 'games' while respecting the order of sorted 'name' if the value of 'games' are the same.
The result should look like this:
array
0 =>
array
'id' => '7'
'name' => 'Xbox 360'
'games' => 1
1 =>
array
'id' => '1'
'name' => 'Playstation 2'
'games' => 2
2 =>
array
'id' => '7'
'name' => 'Playstation 3'
'games' => 2
3 =>
array
'id' => '4'
'name' => 'iPad'
'games' => 5
4 =>
array
'id' => '5'
'name' => 'iPhone'
'games' => 5
5 =>
array
'id' => '6'
'name' => 'iPod Touch'
'games' => 5
I've tried practically all sort functions and user-defined comparison function, but couldn't find the right one.
If it is possible, how can I approach it if I want 'games' DESC while maintaining the sorted 'name' ASC if the value of games are the same? Example:
array
0 =>
array
'id' => '6'
'name' => 'Nintendo DS'
'games' => 5
1 =>
array
'id' => '5'
'name' => 'iPhone'
'games' => 5
2 =>
array
'id' => '4'
'name' => 'iPad'
'games' => 5
3 =>
array
'id' => '1'
'name' => 'Playstation 2'
'games' => 2
4 =>
array
'id' => '7'
'name' => 'Playstation 3'
'games' => 2
5 =>
array
'id' => '7'
'name' => 'Xbox 360'
'games' => 1
usort($array, function ($a, $b) {
if ($a['games'] == $b['games']) {
return strcmp($a['name'], $b['name']);
} else {
return $a['games'] - $b['games'];
}
});
There are other approaches using custom comparison functions, but the simplest approach is with array_multisort.
First create arrays with the keys by which you want to sort your array. Then supply those arrays with the sorting parameters to array_multisort.
// first collect the sorting keys
// ensure that $thearray[$n]['key'] corresponds to $sortkey[$n]
$games = array();
$name = array();
foreach ($thearray as $item) {
$games = $item['games'];
$name = $item['name'];
}
// now sort
array_multisort($games, SORT_NUMERIC, SORT_ASC,
$name, SORT_STRING, SORT_ASC,
$thearray);
// $thearray is now sorted first by games, then by name.