Reputation: 61
How to sort an array based on another array in php? I have this list of persons, actually they are 1300 + people... I will only display 22 people here :)
persons array:
Array (
[0] => Array ( [name] => Kay [site] => ex [rate] => 10 )
[1] => Array ( [name] => Kat [site] => ih [rate] => 9.7 )
[2] => Array ( [name] => Kate [site] => tp [rate] => 9 )
[3] => Array ( [name] => rina [site] => tc [rate] => 9.8 )
[4] => Array ( [name] => Katay [site] => cfnm [rate] => 6.8 )
[5] => Array ( [name] => teriay [site] => sn [rate] => 7.6 )
[6] => Array ( [name] => Kaay [site] => tla [rate] => 9.7 )
[7] => Array ( [name] => na Kay [site] => bsc [rate] => 9.5 )
[8] => Array ( [name] => qwerty [site] => tdp [rate] => 9.5 )
[9] => Array ( [name] => Katey [site] => hd [rate] => 9.4 )
[10] => Array ( [name] => Kat Kay [site] => ss [rate] => 9.2 )
[11] => Array ( [name] => ina Kay [site] => pv [rate] => 9.43 )
[12] => Array ( [name] => ina [site] => rat [rate] => 9.32 )
[13] => Array ( [name] => atay [site] => trw [rate] => 9.32 )
[14] => Array ( [name] => erina [site] => tlm [rate] => 9.43 )
[15] => Array ( [name] => Ky [site] => ol [rate] => 8.34 )
[16] => Array ( [name] => ikay [site] => tb [rate] => 7.34 )
[17] => Array ( [name] => jay [site] => ta [rate] => 6.5 )
[18] => Array ( [name] => saday [site] => hfy [rate] => 4.6 )
[19] => Array ( [name] => tarans [site] => sd [rate] => 6.54 )
[20] => Array ( [name] => dastw [site] => si [rate] => 6.4 )
[21] => Array ( [name] => dyr say [site] => ex [rate] => 7.6 )
)
and there is an another array called site which i want to display them accordingly, only one person per site per loop and when the site array reached to the end then it will start to top until the lists of persons are done reading.
by site order array
Array ( [0] => Array ( [acronym] => exs [site_order] => 1 )
[1] => Array ( [acronym] => ts [site_order] => 1 )
[2] => Array ( [acronym] => ih [site_order] => 2 )
[3] => Array ( [acronym] => tp [site_order] => 3 )
[4] => Array ( [acronym] => tc [site_order] => 4 )
[5] => Array ( [acronym] => cfnm [site_order] => 5 )
[6] => Array ( [acronym] => sn [site_order] => 6 )
[7] => Array ( [acronym] => tla [site_order] => 7 )
[8] => Array ( [acronym] => bsc [site_order] => 8 )
[9] => Array ( [acronym] => tdp [site_order] => 9 )
[10] => Array ( [acronym] => lhd [site_order] => 10 )
[11] => Array ( [acronym] => ss [site_order] => 11 )
[12] => Array ( [acronym] => pov [site_order] => 12 )
[13] => Array ( [acronym] => rat [site_order] => 13 )
[14] => Array ( [acronym] => trw [site_order] => 14 )
[15] => Array ( [acronym] => tgs [site_order] => 15 )
[16] => Array ( [acronym] => tlm [site_order] => 16 )
[17] => Array ( [acronym] => ol [site_order] => 17 )
[18] => Array ( [acronym] => tb [site_order] => 18 )
[19] => Array ( [acronym] => ta [site_order] => 19 )
[20] => Array ( [acronym] => hfy [site_order] => 20 )
[21] => Array ( [acronym] => sd [site_order] => 21 )
[22] => Array ( [acronym] => si [site_order] => 22 )
[23] => Array ( [acronym] => tse [site_order] => 23 )
[24] => Array ( [acronym] => ih [site_order] => 24 )
)
I also want to display them by rate. but I cant even display a correct data because when the site array foreach is finish then it stop loading on people. this is what my code so far...
$x = 0;
$num = 0;
foreach ($site as $item) {
foreach ($data as $person)
{
if($site[$num]['acronym'] == $persons['site'] && $x != 1)
{
echo 'name: '.$person['site'].'<br>';
echo 'site: '.$person['name'].'<br>';
echo '<br>';
$x++;
}
}
$x = 0;
$num++;
}
what output i want is for example:
site: ex
name: kay
rate: 10
site: tp
name: kate
rate: 9
site: tc
name: rina
rate: 9.8
site: ih
name: kat
rate: 9.7
site: tla
name: Kaay
rate: 9.7
.
.
.
and so on
note that I want a condition that: loop persons order by site orders and order by rate but only one person per site loop.
I know it sounds bit complicated but please help me. i searched so much thread here that has the same problem as me, but no luck. :'(
Upvotes: 0
Views: 219
Reputation: 1690
The following code is a possible solution:
$already_printed = Array();
$total_of_people = count($people);
// while there is someone that was not printed yet
while(count($already_printed) < $total_of_people){
// iterate thought each site
foreach($sites as $site){
// take each person and its position in the array
foreach ($people as $i => $person){
// if this i-th person was not printed yet
// and is related to this $site
if (! isset($already_printed[$i])
&& $person['site'] == $site['acronym']){
// print this person
echo 'site: '.$person['site'].'<br>';
echo 'name: '.$person['name'].'<br>';
echo '<br>';
// mark this i-th person as printed
$already_printed[$i] = true;
}
}
}
}
The array already_printed
is used to know who was already printed to avoid double printing. When its size is equal to the total of people, then, we printed everybody, so, we can stop (this is what the outer loop does).
Upvotes: 2
Reputation: 2278
Using your code I would do something like this:
foreach ($site as $item) {
$maxRate = 0;
$savePerson = array();
foreach ($data as $person)
{
if($item['acronym'] == $girls['site'] && $person['site'] == $girls['site'] && $person['rate'] > $maxRate)
{
$maxRate = $person['rate'];
$savePerson = $person;
}
}
if(!empty($savePerson)){
echo 'name: '.$savePerson['site'].'<br>';
echo 'site: '.$savePerson['name'].'<br>';
echo '<br>';
}
}
I don't know exactly if you need this condition $person['site'] == $girls['site'] ..if not you can delete it. That was just my feeling.
btw: you didn't show the $girls array so I just assume is just computed previously. And $data I assume is the $persons array that you are talking about.
Upvotes: 1
Reputation: 2426
The key is to organize that large array into a format that doesn't force you to iterate through it more times than necessary. Give this a shot:
$highest = array();
foreach ($data as $person) {
if (!array_key_exists($person['site'], $highest) || ($person['rate'] > $highest[$person['site']]['rate'])) {
$highest[$person['site']] = $person;
}
}
foreach ($site as $item) {
if (array_key_exists($item['acronym'], $highest)) {
echo "site: {$highest[$item['acronym']]['site']}<br />name:{$highest[$item['acronym']]['name']}<br />rate:{$highest[$item['acronym']]['rate']}";
}
}
As a side note, good call on changing 'girls' to 'person' so this isn't so obviously an application created to rate women...
Upvotes: 1