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;
4
  • 3
    it would be good to show $tabdocids and $datas values Commented Mar 28, 2017 at 13:12
  • Please copy and paste some dummy values from your arrays. Commented Mar 28, 2017 at 13:13
  • 1
    I would unset the element in the $datas array so you don't look at it over and over after it has already been used. Commented Mar 28, 2017 at 13:18
  • $tabdocids contains some integer values , and $datas is an array of objects with object->docid as the id to compare with Commented Mar 28, 2017 at 13:23

3 Answers 3

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);
});
Sign up to request clarification or add additional context in comments.

4 Comments

I don't why this answer get so many upvotes. It's not the SO's purpost. For the order is wrong.
@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.
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.
@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.
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;

Comments

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);
});

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.