How can I sort multidimensional array through key - php

Array
(
[12] => Array
(
[id] => 12
[name] => Car
[children] => Array
(
[0] => Array
(
[id] => 14
[name] => Volvo
)
[1] => Array
(
[id] => 15
[name] => Mercedes-Benz
)
)
)
[13] => Array
(
[id] => 13
[name] => Manga
[children] => Array
(
[0] => Array
(
[id] => 16
[name] => Naruto
)
[1] => Array
(
[id] => 17
[name] => Hunter X Hunter
)
)
)
[18] => Array
(
[id] => 18
[name] => aa
[children] => Array
(
)
)
)
Guys I want to sort the values of this array, i want to sort it by key and the key is 'name'. This should sort the first level and the second level thru key 'name'.
This array i put in print_r() so it looks like this. The array is not fix so i can add in the future.
So after sorting the final value of the array is...
Array
(
[18] => Array
(
[id] => 18
[name] => aa
[children] => Array
(
)
)
[12] => Array
(
[id] => 12
[name] => Car
[children] => Array
(
[0] => Array
(
[id] => 15
[name] => Mercedes-Benz
)
[1] => Array
(
[id] => 14
[name] => Volvo
)
)
)
[13] => Array
(
[id] => 13
[name] => Manga
[children] => Array
(
[0] => Array
(
[id] => 17
[name] => Hunter X Hunter
)
[1] => Array
(
[id] => 16
[name] => Naruto
)
)
)
)
And this is the array in code.
$categories = array(
12 =>
array('id' =>12,
'name' => 'Car',
'children' =>
array(
array('id' => 14,
'name' => 'volvo'
)
),
array(
array('id' => 15,
'name' => 'Mercedez-Benz'
)
)
),
13 =>
array('id' =>13,
'name' => 'Manga',
'children' =>
array(
array('id' => 16,
'name' => 'Naruto'
)
),
array(
array('id' => 17,
'name' => 'Hunter X Hunter'
)
)
),
18=>
array('id' => 18,
'name'=> 'aa',
'children' => array())
);
echo "<pre>";
print_r($categories);

the 'name' is not your real 'Key', just saying, because 'key' in Php normally means the name of your array, like '18' and '12' in your array and so on, like this:
<?php
$fruits = array("d"=>"lemon", "a"=>"orange", "b"=>"banana", "c"=>"apple");
ksort($fruits);
foreach ($fruits as $key => $val) {
echo "$key = $val\n";
}
?>
in this example, the result will be:
a = orange
b = banana
c = apple
d = lemon
anyway to answer your question on how to sort it on 'name', use 'usort':
function cmp($a, $b) {
return $a['name'] - $b['name'];
}
usort($arr,"cmp");
check out the following link for further information:
How do I sort a PHP array by an element nested inside?

if using php 5.3+ you can use closures in your code and sort like this
usort($categories,function($a,$b){
return $a['name'] - $b['name']
}

So,
I'm going to try and explain it better to you
your array is big, yes, but you want to sort only on the key value '[name]'.
In my test I used the array you provided:
$categories = array(
12 =>
array('id' =>12,
'name' => 'Car',
'children' =>
array(
array('id' => 14,
'name' => 'volvo'
)
),
array(
array('id' => 15,
'name' => 'Mercedez-Benz'
)
)
),
13 =>
array('id' =>13,
'name' => 'Manga',
'children' =>
array(
array('id' => 16,
'name' => 'Naruto'
)
),
array(
array('id' => 17,
'name' => 'Hunter X Hunter'
)
)
),
18=>
array('id' => 18,
'name'=> 'aa',
'children' => array())
);
if the array is declared, you can add the usort like this:
usort($categories,"sortByName");
the first element in the above ($categories), is your array, the second element will provide the name of a function, in this case 'sortByName'.
after that, you just add a function into your code (it doesn't really matter where you put it, even if it's at the bottom of the page):
function sortByName($categories, $b) {
return strcasecmp($categories["name"], $b["name"]);
}
Basically what this function does, is compairing your array with ...your array :) so it can sort it alfabetically by name- like you want it.
sthe 'strcasecmp' is to compare your strings against eachother to sort it. not that this is case non sensitive (strcmp will be case sensitive too). I assume you don't want it to check on uppercase and so on too, otherwise the result won't be what you wanted.
when you added that code, you can just print your array again:
echo "<pre>";
print_r($categories);
your result will be:
Array
(
[0] => Array
(
[id] => 18
[name] => aa
[children] => Array
(
)
)
[1] => Array
(
[id] => 12
[name] => Car
[children] => Array
(
[0] => Array
(
[id] => 14
[name] => volvo
)
)
[0] => Array
(
[0] => Array
(
[id] => 15
[name] => Mercedez-Benz
)
)
)
[2] => Array
(
[id] => 13
[name] => Manga
[children] => Array
(
[0] => Array
(
[id] => 16
[name] => Naruto
)
)
[0] => Array
(
[0] => Array
(
[id] => 17
[name] => Hunter X Hunter
)
)
)
I hope this is what you wanted. :-)

Related

How to build tree structure from array in PHP

I have following table:
$arr = array(
array('id'=>100, 'year'=>2019, 'month'=>9, 'name'=>'a'),
array('id'=>101, 'year'=>2019, 'month'=>12, 'name'=>'b'),
array('id'=>102, 'year'=>2020, 'month'=>1, 'name'=>'c'),
array('id'=>103, 'year'=>2020, 'month'=>2, 'name'=>'d'),
);
With the code below
$tree = array();
foreach ($arr as $row) {
$tree[$row['year']] = array(
$row['month'] => array (
'id' => $row['id'],
'name' => $row['name'],
),
);
}
I would like to get following result - this structure as a tree:
Array
(
[2019] => Array
(
[9] => Array
(
[id] => 100
[name] => a
)
[12] => Array
(
[id] => 101
[name] => b
)
)
[2020] => Array
(
[1] => Array
(
[id] => 102
[name] => c
)
[2] => Array
(
[id] => 103
[name] => d
)
)
)
Unfortunately I get only following one with single "branches":
Array
(
[2019] => Array
(
[12] => Array
(
[id] => 101
[name] => b
)
)
[2020] => Array
(
[2] => Array
(
[id] => 103
[name] => d
)
)
)
What is missing here? why previous rows disappear from the structure?
As you want the year and month as the main indexes, you need to use both of these when adding the data into the $tree...
$tree = array();
foreach ($arr as $row) {
$tree[$row['year']][$row['month']] = [ 'id' => $row['id'],
'name' => $row['name']];
}
with your test data, this gives...
Array
(
[2019] => Array
(
[9] => Array
(
[id] => 100
[name] => a
)
[12] => Array
(
[id] => 101
[name] => b
)
)
[2020] => Array
(
[1] => Array
(
[id] => 102
[name] => c
)
[2] => Array
(
[id] => 103
[name] => d
)
)
)
You have mistake in key's names - bl_year, bl_month not exist:
foreach ($arr as $row) {
$tree[$row['year']] = array(
$row['month'] => array (
'id' => $row['id'],
'name' => $row['name'],
),
);
}

PHP - Array unique only using specific values

I have a PHP array that looks like this...
Array
(
[0] => Array
(
[id] => 1
[value] => 111
[date] => 'today'
)
[1] => Array
(
[id] => 2
[value] => 222
[date] => 'today'
)
[2] => Array
(
[id] => 3
[value] => 333
[date] => 'today'
)
[3] => Array
(
[id] => 1
[value] => 111
[date] => 'today'
)
[4] => Array
(
[id] => 5
[value] => 111
[date] => 'today'
)
)
If I use array_unique like this...
print_r(array_unique($array, SORT_REGULAR));
It removes the duplicate [3] which is correct, but I am looking for a way to ignore [id] and only match by [date] and [value] so that my output looks like this...
Array
(
[0] => Array
(
[id] => 1
[value] => 111
[date] => 'today'
)
[1] => Array
(
[id] => 2
[value] => 222
[date] => 'today'
)
[2] => Array
(
[id] => 3
[value] => 333
[date] => 'today'
)
)
array_reduce + array_values() solution:
$arr = [
['id' => 1, 'value' => 111, 'date'=> 'today'],
['id' => 2, 'value' => 222, 'date'=> 'today'],
['id' => 3, 'value' => 333, 'date'=> 'today'],
['id' => 1, 'value' => 111, 'date'=> 'today'],
['id' => 5, 'value' => 111, 'date'=> 'today']
];
$result = array_values(
array_reduce($arr, function($r, $a){
if (!isset($r[$a['value'] . $a['date']])) $r[$a['value'] . $a['date']] = $a;
return $r;
}, [])
);
print_r($result);
The output:
Array
(
[0] => Array
(
[id] => 1
[value] => 111
[date] => today
)
[1] => Array
(
[id] => 2
[value] => 222
[date] => today
)
[2] => Array
(
[id] => 3
[value] => 333
[date] => today
)
)
Iterate over your array and get a key as concatenation of 'date' and 'value' fields. If this key has already been found - skip array value:
$pairs = [];
$new_values = [];
foreach ($array as $item) {
$key = $item['date'] . $item['value'];
if (empty($pairs[$key])) {
$pairs[$key] = 1;
$new_values[] = $item;
}
}

merge two array result wrong array which contain second array as array rather a complete of both

I tries to array_merge in php but resultant array is not correct
1. Array ( [id] => 12 [name] => Popular )
2. Array ( [0] => Array ( [id] => 8 [name] => Flowers ) [1] => Array ( [id] => 10 [name] => Chocolates ) [2] => Array ( [id] => 11 [name] => Sweets and Dry Fruits ) )
Resultant Array
Array ( [id] => 12 [name] => Popular [0] => Array ( [id] => 8 [name] => Flowers ) [1] => Array ( [id] => 10 [name] => Chocolates ) [2] => Array ( [id] => 11 [name] => Sweets and Dry Fruits ) )
If you just want to add the new data in the same format as the existing data then use [] rather than array_merge().
$array1 = array( 'id' => 12, 'name' => 'Popular');
$array2 = array(array( 'id' => 8, 'name' => 'Flowers'),
array( 'id' => 10, 'name' => 'Chocolates'),
array( 'id' => 11, 'name' => 'Sweets and Dry Fruits')
);
$array2[] = $array1;
print_r($array2);
outputs...
Array
(
[0] => Array
(
[id] => 8
[name] => Flowers
)
[1] => Array
(
[id] => 10
[name] => Chocolates
)
[2] => Array
(
[id] => 11
[name] => Sweets and Dry Fruits
)
[3] => Array
(
[id] => 12
[name] => Popular
)
)
If you want the data to be at the front, then you need to create an array of that data and then use array_merge()...
$array3 = array_merge(array($array1), $array2);
print_r( $array3);

array one format to another

I have one array in two format. I want to change array from
Array
(
[step_number] => 4
[app_id] => Array
(
[0] => 2
[1] => 3
)
[formdata] => Array
(
[0] => Array
(
[name] => app_id[]
[value] => 2
)
[1] => Array
(
[name] => app_id[]
[value] => 3
)
[2] => Array
(
[name] => fieldval[2][2][]
[value] => 1
)
[3] => Array
(
[name] => fieldval[3][3][]
[value] => 200
)
[4] => Array
(
[name] => fieldval[3][3][]
[value] => day
)
[5] => Array
(
[name] => title
[value] => new plan
)
[6] => Array
(
[name] => feature_plan
[value] => 3
)
[7] => Array
(
[name] => plan_type
[value] => free
)
[8] => Array
(
[name] => price
[value] =>
)
[9] => Array
(
[name] => sell_type
[value] => us
)
)
)
this format to
Array
(
[app_id] => Array
(
[0] => 2
[1] => 3
)
[fieldval] => Array
(
[2] => Array
(
[2] => Array
(
[0] => 1
)
)
[3] => Array
(
[3] => Array
(
[0] => 200
[1] => day
)
)
)
[title] => new plan
[feature_plan] => 3
[plan_type] => free
[price] =>
[sell_type] => us
)
these are are one array into two format. i have data in to first array format and i want to change that format to second array type format.
please tell me how i am trying this for 2 days but not succeed.
Here is a function you could use to produce that conversion:
function convert_formdata($input) {
$output = array();
foreach($input['formdata'] as $data) {
$keys = preg_split("#[\[\]]+#", $data['name']);
$value = $data['value'];
$target = &$output;
foreach($keys as $key) {
// Get index for "[]" reference
if ($key == '') $key = count($target);
// Create the key in the parent array if not there yet
if (!isset($target[$key])) $target[$key] = array();
// Move pointer one level down the hierarchy
$target = &$target[$key];
}
// Write the value at the pointer location
$target = $value;
}
return $output;
}
You would call it like this:
$output = convert_formdata($input);
See it run on eval.in for the given input. The output is:
array (
'app_id' =>
array (
0 => 2,
1 => 3,
),
'fieldval' =>
array (
2 =>
array (
2 =>
array (
0 => 1,
),
),
3 =>
array (
3 =>
array (
0 => 200,
1 => 'day',
),
),
),
'title' => 'new plan,',
'feature_plan' => 3,
'plan_type' => 'free',
'price' => NULL,
'sell_type' => 'us',
)

convert multidimensional array into two separated

I have a multidimensional Array like this:
Array (
[0] => Array (
[id] => 1
[name] => privilages1
)
[1] => Array (
[id] => 2
[name] => privilages2
)
[2] => Array (
[id] => 3
[name] => privilages3
)
[3] => Array (
[id] => 4
[name] => privilage4 )
[4] => Array (
[id] => 5
[name] => privilages5 )
)
and i want to compare it with another array, which looks like this:
Array (
[0] => Array (
[id] => 1 )
[1] => Array (
[id] => 2)
)
if the value of id matches, then i want to all values from the first example.
How can i do this?
You can use array_filter to filter the array elements you want by supplying a user defined callback function.
Here is the code:
$arr = array( array('id' => 1, 'name' => 'foo'),
array('id' => 2, 'name' => 'bar'),
array('id' => 3, 'name' => 'baz'),
array('id' => 4, 'name' => 'wow'));
$ret = array_filter($arr, create_function('$el',
'static $search=array(array("id" => 1), array("id" => 2));
$n=array("id" => $el["id"]);
return (array_search($n, $search) !== false);'));
print_r($ret);
OUTPUT
Array
(
[0] => Array
(
[id] => 1
[name] => foo
)
[1] => Array
(
[id] => 2
[name] => bar
)
)

Categories