Sorting Multidimensional Array - php

Thought I will point out first that I have looked around on Stackoverflow and the internet already and although they are plenty of examples none of them are explained into such a way for me to understand how to convert the code to work with my array structure.
I believe I need to use one of the functions uksort or uasort but unsure on this as well.
My array looks like the following.
Array
(
[0] => Array
(
[Result] => Array
(
[id] => 260
[event_id] => 72
[year] => 2010
[york_score] => 27
[york_points] => 0.0
[lancs_score] => 51
[lancs_points] => 4.0
[winner] => L
[confirmed] => Y
[updated] => 2010-05-01 16:10:03
)
[Event] => Array
(
[id] => 72
[sport_id] => 25
[event_title] => 1st Team
[Sport] => Array
(
[id] => 25
[sport_title] => Netball
)
)
)
And where its [0] means it continues on.
I need to sort all of the arrays [0,1,2,3,...] by the sport_title key found in [Event][Sport]
Does anyone know how to create a sorting function to do this?
Some explanation of how the function is working would also be helpful if I later need to adapter/alter the code to work else where on my site.

Where $array is the name of the array which holds the array you posted in your question.
function sort_multi($item_1, $item_2)
{
// strcmp looks at two strings and, based off the characters' and their order,
// determines which one is numerically greater. When this function returns a
// negative, for example, it means the first item it's comparing is less that the
// second item (ef and eg, for example). The usort function then rearranges
// the array based off these comparisons.
return strcmp($item_1['Event']['Sport']['sport_title'], $item_2['Event']['Sport']['sport_title']);
}
usort($array, 'sort_multi');

Related

Find if all elements in one multidimensional arrays exists in another (using a multidimensional array as a haystack)

I have been trying to use some logic to be able to see if all elements in a multidimensional array (haystack) exits in another much larger haystack. My first haystack comes from a json object in the first place, and the second one is a "dot name" string, that is also converted into an array. The logic here is that I can use a string describing what I'm looking for in the json in a simple way:
Needle:
Array
(
[key1] => Array
(
[provider] => Array
(
[id] => 1
)
)
[key2] => Array
(
[consumer] => Array
(
[id] => 5
)
[hostname] => foo
)
)
Haystack:
[0] => Array
(
[id] => 1000
[consumer] => Array
(
[id] => 5
[name] => test
[hostname] => foo
[1] => Array
(
[id] => 1200
[provider] => Array
(
[id] => 5
[name] => test
If the needle exists in the array the top key should be returned. So if we pretend all key->values below "key2" exists in array we should return key2. provider-id and consumer-id are not the same and there might be other key-values that might look the same, but has a different path. so if "hostname" would exists, but much deeper into array that is not a match.
The problem is that all examples I've come across either have:
A fixed depth on the array.
Having the needle as a string.
Is not true multidimensional.
Is there a way this can be done? recursiveiteratoriterator did come to my mind but not sure actually how to use it, based on the above.
I've also looked at various in_array/is_array/array_map/array_filter recursive examples but they are fell a bit messy and I couldn't decide if it was worth trying to build something that would allow to crawl two arrays in a good way.
My array is quite large and contains, sadly mostly items I'm not interested in. But if I can find a way that works I'm sure I can optimize that part.
Thanks for reading.

How can I access ID array of its value

I am analyzing someone's else code where I found during debugging the type and values of a class variable during run time:
echo print_r($this->_out);
Array
(
[id] => -1
[fieldErrors] => Array
(
)
[error] =>
[data] => Array
(
)
[row] => Array
(
[DT_RowId] => row_177
[id] => 177
[last_name] => sdfdsf
[first_name] => dsf
[homeaddr] => sdfdsfsdfdsfdsfdsfdsf
[email] => s#jj.com
[officeaddr] => wwwwwwwwwwwwwwwwwwwwwwww
[mobile] => 11111111
[age] => 11
[chargeamt] => 11
[start_date] => 11/11/2011
)
)
1{"row":{"DT_RowId":"row_177","id":"177","last_name":"sdfdsf","first_name":"dsf","homeaddr":"sdfdsfsdfdsfdsfdsfdsf","email":"s#jj.com","officeaddr":"wwwwwwwwwwwwwwwwwwwwwwww","mobile":"11111111","age":"11","chargeamt":"11","start_date":"11\/11\/2011"}}
I am a newbie in PHP and would like to know how I can access [id] => 177 value i.e. value 177.
I tried out many ways
$this->_out['row']['id'][0]
It gave me below result:
1{"row":{"DT_RowId":"row_177","id":"177","last_name":"sssss","first_name":"ss","homeaddr":"sssssssssssssssssssss","email":"ss#ww.com","officeaddr":"sssssssssssssssssssssssssssss","mobile":"11111111","age":"11","chargeamt":"11","start_date":"01\/01\/2001"}}
while
I tried out many ways
$this->_out['row']['id']
It gave me below result:
177{"row":{"DT_RowId":"row_177","id":"177","last_name":"sssss","first_name":"ss","homeaddr":"sssssssssssssssssssss","email":"ss#ww.com","officeaddr":"sssssssssssssssssssssssssssss","mobile":"11111111","age":"11","chargeamt":"11","start_date":"01\/01\/2001"}}
and others but its just not giving me the expected.
How can I access the value as desired?
You are doing it right. $this->_out['row']['id'] will return desired result (check why you get also JSON string that is not part of print_t($this->_out).
This will return result 177:
$this->_out['row']['id'];
And since in PHP you can access string characters as array, this will returns first character in string (that is 1):
$this->_out['row']['id'][0];
And this will throw error as there is no such index (string length is 3, so last index is 2):
$this->_out['row']['id'][5];
The print_r result is an array with more arrays on it. So first of all you must find the index of the main array which index represents the sub-array with the value you are looking for. And then you must use this index to access the sub array values.

Sort an array according to a set of values from another array

I am aware there is another question on SO which is supposed to answer the same thing. My problem is that I don't see what array merge has do do with anything. I don't want to merge the arrays necessarily and I don't understand how that would help ordering them ... also I don't understand where the ordering is coming into it.
If it is relevant could someone please explain in a bit more detail whether the other answer would work for me or not and how
Here is what I have ( the array is quite large so this is a simplification )
Essentially I have something like this
Array (
[0] => stdClass Object (
[term_id] => 72
[name] => name
[slug] => slug
[term_group] => 0
[term_order] => 1
[term_taxonomy_id] => 73
[taxonomy] => gallery_category
[description] => description
[parent] => 78
[count] => 85 )
[1] => stdClass Object (
[term_id] => 77
[name] => name
[slug] => slug
etc, etc, etc, there are a lot of objects in the array
Then I have an ordering array like
Array (
[0] => 77,
[1] => 72,
etc
So what I want to do is to impose the ordering of the second array on the first one - the ordering array holds the value of the [term_id] from the second array in the corrrect order. In the example above that would mean that I would reverse the order of the first two objects.
$order_array = [77, 72];
$order_array = array_flip($order_array);
usort($objects, function($a, $b) use ($order_array)
{
return $order_array[$a->term_id] - $order_array[$b->term_id];
});
This assumes that $order_array has an entry for every term_id.
uksort could do it.
function cmp($a, $b)
{
$ordering_array=array(0=>77, 1=>72);
return $ordering_array[$a] - $ordering_array[$b];
}
$a = array() #etc...
uksort($a, "cmp");

How to sort the following array?

I am fetching records from database which returns an array as follows:
Array
(
[0] => stdClass Object
(
[id] => 2
[name] => ravi
[text] => hey
[date] => 2011-05-1
)
[1] => stdClass Object
(
[id] => 3
[name] => shiv
[text] => bye
[date] => 2011-04-29
)
[2] => stdClass Object
(
[id] => 4
[name] => adi
[text] => hello
[date] => 2011-04-30
)
)
How to sort this based on the date element?
You should sort this before you actually fetch it, meaning use the 'ORDER BY' clause already in your database query!
Why?
because you write much less code
because it is faster
because it is easier to refactor
You may find the usort() function useful: http://docs.php.net/manual/en/function.usort.php
You could pass in as the second parameter the following function:
function cmp($a, $b)
{
if ($a->date == $b->date) {
return 0;
}
return ($a->date < $b->date) ? -1 : 1;
}
Ideally you should be sorting within the query itself, using ...ORDER BYdate..
..but if you really wanna do it with php, look at the user notes in the manual under sort, there are examples of how to sort like that (and you can apply with rsort() or asort() or arsort() depending on if you want to preserve keys or sort descending or whatever)

PHP - Combine sub-arrays and sort by value?

This is what i've got now:
Array
(
[0] => Array
(
[0] => Array
(
[id] => 53
[date] => 18 Sep 2010 10:29
[user] => 52
[post] => ytiuy
)
[1] => Array
(
[id] => 55
[date] => 11 Sep 2010 11:14
[user] => 52
[post] => this is a test post :]
)
)
[1] => Array
(
[0] => Array
(
[id] => 56
[date] => 4 Sep 2010 03:19
[user] => 55
[post] => pppost :DD:D:D:D
)
)
)
I want to remove the first two "steps" in the array, and then sort the array by the 'date' value, like this:
Array
(
[0] => Array
(
[id] => 56
[date] => 4 Sep 2010 03:19
[user] => 55
[post] => pppost :DD:D:D:D
)
[1] => Array
(
[id] => 55
[date] => 11 Sep 2010 11:14
[user] => 52
[post] => this is a test post :]
)
[2] => Array
(
[id] => 53
[date] => 18 Sep 2010 10:29
[user] => 52
[post] => ytiuy
)
)
Any ideas?
Thanks a bunch, appreciate all help! :)
EDIT: I should also mention that the amount of arrayitems will not always be the same.
You should be able to use an accumulator pattern with the array_merge function to merge all the lower level arrays together.
$result = array();
foreach ($oldarray as $child)
{
$result = array_merge($result, $child);
}
Finally, you can use the user defined sort function to sort the whole thing.
An alternative to Don Kirby's solution would be to use an SplMaxHeap which would allow you to iterate and sort in one go:
class PostHeap extends SplMaxHeap
{
public function compare($post, $other)
{
return strtotime($post['date']) - strtotime($other['date']);
}
}
$postHeap = new PostHeap;
foreach($posts as $subArray) {
foreach($subArray as $post) {
$postHeap->insert($post);
}
}
The $postHeap would then contain the posts in descending date order, e.g. newest date first. You can use the code in the compare function if you want to use usort instead. The order will be ascending then though.
Do you have two arrays? Or more? Are they already sorted? If so, you can use that to combine them more efficiently. If not, you probably need to sort them first.
Roughly:
Sort your input arrays (optionally)
Scan your input arrays for the lowest value, copy that value into your new array, delete the value from the input array.
Repeat until all your input arrays are empty.
Of course, if you don't care about performance at all you could simply combine all the arrays and then sort that.
And for sorting you may want to use: http://www.php.net/manual/en/function.sort.php#99700
#Don Kirkby: Indeed: It's basically a mergesort, but it only works on already sorted arrays. If they're both unsorted you're probably better off with combining them and using quicksort instead.

Categories