PHP sort array alphabetically - php

I'm struggling on this one. I have an array that contains countries and regions. I want to sort both sets of information in ascending order on the key.
Here is the array I'm working with:
Array
(
[Country] => Array
(
[United Kingdom] => Array
(
[London] => Array
(
[0] => 1
[1] => 5
[2] => 23
[3] => 71
)
[Manchester] => Array
(
[0] => 800
)
)
[United States] => Array
(
[New York] => Array
(
[0] => 147
[1] => 111
)
[Washington] => Array
(
[0] => 213
)
[Florida] => Array
(
[0] => 6
)
[Texas] => Array
(
[0] => 9
)
)
[Brazil] => Array
(
[Brasília] => Array
(
[0] => 64
)
)
)
)
So the reordered array would be:
Brazil
- Brasília
United Kingdom
- London
- Manchester
United States
- Florida
- New York
- Texas
- Washington
The data structure should remain the same, but the order of the number (e.g. London: 1,5,23,71) can stay the same.
I've tried several of the sorting methods from:
http://php.net/manual/en/array.sorting.php
But they dont appear to do anything. Maybe because its a multidimensional array or maybe its not structured 100% logically... but I'm stuck with the array as it is.

You can try:
ksort_recursive($data);
print_r($data);
Function Used
function ksort_recursive(&$array) {
ksort($array);
foreach ( $array as &$a ) {
is_array($a) && ksort_recursive($a);
}
}
See Testing on Multiple PHP Versions

Step 1:
Sort the country by key.
ksort($arr['Country']);
Step 2: Loop through the countries and sort those keys.
foreach ($arr['Country'] as $country=>$data) {
ksort($arr['Country'][$country]);
}

Related

PHP array - count unique IDs

I have a PHP array that looks like this
Array
(
[0] => Array
(
[events] => Array
(
[0] => Array
(
[label] => apple
[id] => 3
)
[1] => Array
(
[label] => onion
[id] => 3
)
[2] => Array
(
[label] => pear
[id] => 2
)
[3] => Array
(
[label] => orange
[id] => 1
)
[4] => Array
(
[label] => grape
[id] => 41
)
)
)
)
I am trying to get a total count of unique IDs, so in the example above I would want to get a count of 4
Do I need to loop through the array or is there a function that can do it more efficiently? Currently it is a small data set but it could grow fairly large.
You can use array_column to get all the IDs, and array_unique to remove the duplicates, then count that.
count(array_unique(array_column($array[0]['events'][0], 'id')))
One way or another you'll have to loop through it. I think most efficiently would be
function getUnique($arr){
$val = array();
foreach($arr[0]["events"] as $v){
$val[$v["id"]] = true;
}
return count($val);
}

How to match and relate data unique?

I'm having some difficulties figuring out how to return the best unique match, while assigning as many as possible.
Scenario: Each kid has a list of favorite fruits with a personal score. We only have ONE of each fruit, so we want to give it to the kid with the highest preference. One can be left without fruit if someone has a higher score, but we still want to give out as many fruits as possible.
The expected result would be:
0 = [1] Apple
1 = [0] Mango
2 = [0] Banana
3 = null
This is my input array:
Array
(
[0] => Array
(
[0] => Array
(
[name] => Banana
[score] => 80.2
)
[1] => Array
(
[name] => Apple
[score] => 40
)
)
[1] => Array
(
[0] => Array
(
[name] => Mango
[score] => 70
)
[1] => Array
(
[name] => Banana
[score] => 40
)
)
[2] => Array
(
[0] => Array
(
[name] => Banana
[score] => 90
)
[1] => Array
(
[name] => Orange
[score] => 20
)
)
[3] => Array
(
[0] => Array
(
[name] => Mango
[score] => 60
)
)
)
My approach first flattens your input into a simple 2D array allowing all rows to be sorted by score while preserving the fruit and childid data. After sorting, all rows are iterated (versus doing iterated full-array searches) and only stores the most preferred fruit, if available, for each child as requested.
OP's Input:
$input=[
[['name'=>'Banana','score'=>80.2],['name'=>'Apple','score'=>40]],
[['name'=>'Mango','score'=>70],['name'=>'Banana','score'=>40]],
[['name'=>'Banana','score'=>90],['name'=>'Orange','score'=>20]],
[['name'=>'Mango','score'=>60]]
];
Method:
$result=array_fill_keys(array_keys($input),null); // list all child ids and default to null
// flatten input array for simple sorting and iteration
foreach($input as $i=>$subarrays){
foreach($subarrays as $a){
$restructured[]=['score'=>$a['score'],'fruit'=>$a['name'],'childid'=>$i];
}
}
rsort($restructured); // will sort the array by score DESC
foreach($restructured as $a){
if(is_null($result[$a['childid']]) && !in_array($a['fruit'],$result)){
// only "fruitless" children wanting what is available
$result[$a['childid']]=$a['fruit'];
}
}
var_export($result);
Output:
array (
0 => 'Apple',
1 => 'Mango',
2 => 'Banana',
3 => NULL,
)

Creating associative arrays php for dynamic accordian

Hello I am creating a dynamic accordian with the values from database.
I am stuck in looping the array . Please help.
I have an array similar to this
Array
(
[0] => Array
(
[0] => Array
(
[0] => real estate
)
[1] => Array
(
[0] => flatvcvjh
[1] => villayuiuyidd
)
)
[1] => Array
(
[0] => Array
(
[0] => real estate
[1] => iooi
)
[1] => Array
(
[0] => y
)
)
[2] => Array
(
[0] => Array
(
[0] => real estate
[1] => iooi
[2] => painting
)
[1] => Array
(
[0] => interior
[1] => exterior
)
)
[3] => Array
(
[0] => Array
(
[0] => real estate
[1] => iooi
[2] => painting
[3] => contruction
)
[1] => Array
(
[0] => house
[1] => compound
)
)
)
Following is the loop m using to get the above array
foreach($parent_categories as $parent_category) {
$sub_categories=//array of sub cat;
$arr[]=$parent_category->name;
$scat_name="";
foreach($sub_categories as $sub_category) {
//get sub categories
$scat_name[]=$sub_category->name;
}
$subcat_name[]=$arr;
$subcat_name[]=$scat_name;
$project_categories[] = $subcat_name;
$subcat_name="";
}
echo "<pre>";
print_r($project_categories);exit;
The above loop i tried is for 2 levels.
I need a 3 dimensional array with 3 levels of categories
like
category1
subcat1
subcat2
subsubcat1
subsubcat2
subcat3
what changes will i have to make in the above loop I tried number of ways the above is what I get. Please help
Use recursive function
$menusList = array();
function dynamic_menus($menus) {
foreach($menus as $index => $subMenu) {
menusList[$index] = is_array($subMenu) ? dynamic_menus($subMenu) : $subMenu;
}
return menusList;
}
you need to convert array to object first beacause you use
$sub_category->name is to read object type
Multidimensional array to object, specific way
http://php.net/manual/en/language.types.object.php

What does [1] => 0 mean in this array?

I know this must be a fairly simple question, but I haven't managed to stumble across an answer yet.
I have the following array
$qid[0][0]=1;
$qid[1][0]=2;
$qid[2][0]=3;
$qid[3][0]=4;
When I use print_r($qid) I get the following
Array (
[0] => Array ( [0] => 1 [1] => 0 )
[1] => Array ( [0] => 2 )
[2] => Array ( [0] => 3 )
[3] => Array ( [0] => 4 )
)
I don't understand [1] => 0
in
[0] => Array ( [0] => 1 [1] => 0 )
If someone could explain what [1] => 0 means in this array, I'd greatly appreciate it. Thanks.
EDIT: It turns out that my array was indeed different to what I had written above, because it had been modified later in the code. Thanks everyone for the great answers. I'm still reading over them all and trying to make my mind understand them (Arrays turn my mind to jello).
[1] => 0 denotes an array element with the value 0.
The numbers in [] are array keys. So [1] is the second element of a numerically indexed array, (which starts with [0]), and the value of the second element ([1]) is 0.
PHP uses => as an operator to relate array keys/indices to their values.
So an overall explanation of this structure:
Array (
[0] => Array ( [0] => 1 [1] => 0 )
[1] => Array ( [0] => 2 )
[2] => Array ( [0] => 3 )
[3] => Array ( [0] => 4 )
)
The outer array is a numerically indexed array, and each of its elements is a sub-array. The first of them ([0]) is an array containing 2 elements, while the rest of them ([1] through [3]) are arrays containing only one single element.
That two-dimensional array is actually a one-dimensional array of arrays, which is why you're getting the nesting. The [x] => y bit simply means that index x of the array has the value y.
Now your output in this case doesn't actually match your code, since
$qid[0][0]=1;
$qid[1][0]=2;
$qid[2][0]=3;
$qid[3][0]=4;
print_r($qid);
produces:
Array (
[0] => Array ( [0] => 1 )
[1] => Array ( [0] => 2 )
[2] => Array ( [0] => 3 )
[3] => Array ( [0] => 4 )
)
If you wanted to get:
Array (
[0] => Array ( [0] => 1 [1] => 0 )
[1] => Array ( [0] => 2 )
[2] => Array ( [0] => 3 )
[3] => Array ( [0] => 4 )
)
(with the first array having two elements), you'd actually need:
$qid[0][0]=1;
$qid[0][1]=0;
$qid[1][0]=2;
$qid[2][0]=3;
$qid[3][0]=4;
print_r($qid);
You probably added a second item to $qid[0] somewhere ($qid[0][1] = 0). This code
$qid[0][0]=1;
$qid[1][0]=2;
$qid[2][0]=3;
$qid[3][0]=4;
outputs the the correct values for me (without [1] => 0:
Array ( [0] => Array ( [0] => 1 ) [1] => Array ( [0] => 2 ) [2] => Array ( [0] => 3 ) [3] => Array ( [0] => 4 ) )
It means that your index 0 in the original Array contains another Array of 2 items.
Specifically [1] => 0 means that the 2nd item of the "child" Array contains the number 0.
[1] => 0
in this simple way we can say that 1 is your array key and 0 is value for the 1 key
0 is store at the 1 key of the array
thanks
Simply put, you have a numerically indexed multidimensional array. http://php.net/manual/en/language.types.array.php should have all the information you need to read up on this.
As to why you have the [1] => 0, you'll need to look a little deeper into your code to see where it gets assigned.
I got the following result after printing out the array using print_r:
Array
(
[0] => Array
(
[0] => 1
)
[1] => Array
(
[0] => 2
)
[2] => Array
(
[0] => 3
)
[3] => Array
(
[0] => 4
)
)
I guess, you might have set a value for $gid[0][1] somewhere in your code.

php unique/group associative array

I would like to remove duplicates for the following array. I want to group by the first value and then rebuild the index.
ie
Array
(
[0] => Array
(
[title] => California
[state_id] => 1
)
[1] => Array
(
[title] => California
[state_id] => 1
)
[2] => Array
(
[title] => New Mexico
[state_id] => 2
)
[3] => Array
(
[title] => Washington
[state_id] => 3
)
[4] => Array
(
[title] => Montana
[state_id] => 4
)
[5] => Array
(
[title] => Montana
[state_id] => 4
)
)
To
Array
(
[0] => Array
(
[title] => California
[state_id] => 1
)
[2] => Array
(
[title] => New Mexico
[state_id] => 2
)
[3] => Array
(
[title] => Washington
[state_id] => 3
)
[4] => Array
(
[title] => Montana
[state_id] => 4
)
)
and rebuild key
Array
(
[0] => Array
(
[title] => California
[state_id] => 1
)
[1] => Array
(
[title] => New Mexico
[state_id] => 2
)
[2] => Array
(
[title] => Washington
[state_id] => 3
)
[3] => Array
(
[title] => Montana
[state_id] => 4
)
)
$array = array_values(array_combine(array_map(function ($i) { return $i['title']; }, $array), $array));
I.e.
extract the title key (array_map)
use the extracted titles as keys for a new array and combine it with the old one (array_combine), which de-duplicates the array (keys have to be unique)
run the result through array_values, which discards the keys
Broken down:
$keys = array_map(function ($i) { return $i['title']; }, $array);
$deduped = array_combine($keys, $array);
$result = array_values($deduped);
For PHP 5.2- you'll need to write the anonymous callback function like this:
array_map(create_function('$i', 'return $i["title"];'), $array)
Sort your array by title (usort does the trick)
create a new empty array
Cycle original array and store the value you find in the new empty array
If next array value equals last then skip it
At the end of this you have the array you want.
There is another way:
Sort your array by title
Cycle original array
If this array value equals last then unset it
Sort the array again with PHP sort function to rebuild keys
$array = array_unique($array);
Yes, it works with multi-dimentional arrays too; it just checks to equality.

Categories