xerwudjohn
xerwudjohn

Reputation: 61

How to sort an array based from another array in php?

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

Answers (3)

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

Edwin
Edwin

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

rawb
rawb

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

Related Questions