3

Is there a better way to sort the $datas array in the order of the $tabdocids values ?

foreach ( $tabdocids as $ordered_id ) {
            foreach ( $datas as $doc )
                if ($doc->docid == $ordered_id)
                    $ordered [] = $doc;
}
$datas=$ordered;
LF00
  • 27,015
  • 29
  • 156
  • 295
Matoeil
  • 6,851
  • 11
  • 54
  • 77

3 Answers3

5

One way to rome...

#for collect
$ordered = array_flip($tabdocids);//too keep the order from the $tabdocids
array_map(function ($doc) use ($tabdocids,&$ordered){ 
      if(in_array($doc->docid,$tabdocids)){ $ordered [$doc->docid] = $doc; } 
},$datas);
$datas=array_values($ordered);

[updated after comment from @Kris Roofe] now it will be sorted.

or without sorting

$datas = array_filter($datas,function ($doc) use ($tabdocids){ 
      return (bool)in_array($doc->docid,$tabdocids);
});
JustOnUnderMillions
  • 3,741
  • 9
  • 12
  • I don't why this answer get so many upvotes. It's not the SO's purpost. For the order is wrong. – LF00 Mar 28 '17 at 13:56
  • @Kris Roofe `Is there a better way` means not that the current script is not working (but will also not order right). So my examples do the same. As long no more infor are given, it is the best. I wanted to use `$ordered [$doc->docid] = $doc;` for sorting later, but there is no information about id dublicates. So i give 2 other versions and that what the SO ask for. – JustOnUnderMillions Mar 28 '17 at 14:32
  • You answer order is wrong. The SO want $datas in $tabdocids order not $datas order. SO first search $datas in the $tabdocids order, if $datas's docid not in $tabdoids then in $datas order. – LF00 Mar 28 '17 at 14:36
  • @Kris Roofe If the $tabdocids array is order order, then my answer works. But whatever, SO is away, nobody will get a check here. I just pointed a direction. And give 2 examples. Your answer is little too mutch for a noob coder. More than copy past will not happen with it. – JustOnUnderMillions Mar 28 '17 at 14:42
2

Try this, it uses single loop over $datas by using the map for tabdocids

   $flipeddocids=array_flip(tabdocids);
     $ordered = [];
     foreach ( $datas as $doc ) {
        $ordered[$flipeddocids[$doc->docid]]=$doc;
     }
     $datas=$ordered;
1

You can calculate the order sequence first. Then use the order to rearrange $datas, this will reduce a lot of calculation.

$order = array_flip(array_values(array_unique(array_intersect($tabdocids, array_column((array)$datas, 'docid')))));
usort(&$datas, function($a, $b) use($order){
    return isset($order[$a->docid]) ? isset($order[$b->docid]) ? $order[$a->docid] <=> $order[$b->docid] : -1 : (isset($order[$b->docid]) ? 1 : -1);
});
LF00
  • 27,015
  • 29
  • 156
  • 295