0

I'm trying to get indexes(keys) from the unsorted array but something I'm doing wrong. This is my two arrays:

$unsorted = [1,2,1,14,3,1,3,6,1,13,83,4, 4 ,68];
$sorted = [83,68,14,13,6,4,4,3,3,2,1,1,1,1];

I tried the array_keys().The below code is working

$a = array_keys($unsorted,$sorted[0]);
print_r($a);
echo '<br>';

The output

Array ( [0] => 10 )

but inside for loop it is not. please suggest me where I'm doing wrong

for($y=0;$y<sizeOf($sorted);$y++) {
    $final_keys = array_keys($unsorted,$sorted[$y]);
    //$final[] = $final_two[$y];
}
print_r($final_keys);

The output is

Array ( [0] => 0 [1] => 2 [2] => 5 [3] => 8 )

what I expect is

Array ( [0] => 10 [1] => 13 [2] => 3 [3] => 9 [4] => 7 [5] => 11 [6] => 12 [7] => 4 [8] => 6 [9] => 1 [10] => 0 [11] => 2 [12] => 5 [13] => 8 )

Barry
  • 3,303
  • 7
  • 23
  • 42
Aroon
  • 991
  • 2
  • 15
  • 34

5 Answers5

2

Loop $sorted, find the key/value pair in $unsorted and store. And set the value in $unsorted (I made a copy, not to destroy the original) to false, otherwise 1 would always find the first value of 1.

$unsorted = [1,2,1,14,3,1,3,6,1,13,83,4, 4 ,68];
$sorted = [83,68,14,13,6,4,4,3,3,2,1,1,1,1];
$copy = $unsorted;
$output=[];

foreach ($sorted as $key => $value){
  $reference = array_search( $value , $copy );
  $output[$key] = $reference;
  $copy[$reference] = false;
  }

Result:

Array
(
    [0] => 10
    [1] => 13
    [2] => 3
    [3] => 9
    [4] => 7
    [5] => 11
    [6] => 12
    [7] => 4
    [8] => 6
    [9] => 1
    [10] => 0
    [11] => 2
    [12] => 5
    [13] => 8
)
Michel
  • 4,076
  • 4
  • 34
  • 52
  • In this output the second index is not 9 its 13. please have a look – Aroon Oct 26 '18 at 10:57
  • @Aroon. The second value in `$unsorted` is `2`. The key of value `2` in `$sorted` is `9`. Hence `[1] => 9`. – Michel Oct 26 '18 at 11:01
  • There I'm looking for 13 cuz 68th index value is 13 in $unsorted – Aroon Oct 26 '18 at 11:07
  • @mickmackusa. I don't see why not. `array_search()` just looks for the value, returning the key. – Michel Oct 26 '18 at 11:07
  • @Aroon, you want it the other way round? Not `$unsorted => $sorted` but `$sorted => $unsorted`? – Michel Oct 26 '18 at 11:09
  • sorry to confusing you. I want to get the values from sorted array and based on the values i want keys from unsorted array. like 83's key should be 10 and 68 th should be 13 like so on – Aroon Oct 26 '18 at 11:15
2

You can simply sort your array while maintaining the index association, and then gets the keys of the resulting array:

$unsorted = [1,2,1,14,3,1,3,6,1,13,83,4, 4 ,68];
$temp = $unsorted; // create a copy, in case you need still need the unsorted version later on
arsort($temp); // sort values in reverse order, while keeping the keys
$keys = array_keys($temp);
var_dump($keys);
misorude
  • 3,381
  • 2
  • 9
  • 16
  • @Aroon Is there anything that isn't absolutely perfect about this answer? – mickmackusa Oct 26 '18 at 11:07
  • @mickmackusa I’m getting a slightly different result here with my code, than in the question/accepted answer, `[0]=>10 [1]=>13 [2]=>3 [3]=>9 [4]=>7 [5]=>11 [6]=>12 [7]=>6 [8]=>4 [9]=>1 [10]=>2 [11]=>5 [12]=>0 [13]=>8` I guess the duplicate values in the original data make it slightly ambiguous, what should be considered the “correct” result here. – misorude Oct 26 '18 at 13:12
  • Something is strange to me. I'm pretty sure if this was my project, I'd be doing what you're doing. Perhaps I'll re-read this page a few times. Perhaps php's Quick Sort is to blame. – mickmackusa Oct 26 '18 at 13:15
  • @mickmackusa I guess the difference comes from that my solution maintains the index association throughout, whereas with the original question and the already given “sorted” data, there is no way to tell _which_ of the `1,1,1,1` at the end was which to begin with. And then when `array_search` gets used (on $copy, in the accepted answer), it will always find the _first_ 1 every time, because it can’t differentiate between the multiple occurrences either ... – misorude Oct 26 '18 at 13:23
  • Ah ha! Nope, not your fault. It's a php version issue. PHP5.6 doesn't sort the duplicates like php7+. Look at this: https://3v4l.org/TYkkb upvoting this answer because it will be faaaaaaar more efficient than iterated `array_search()` calls. – mickmackusa Oct 26 '18 at 13:33
  • @Aroon what php version are you using? – mickmackusa Oct 26 '18 at 13:34
  • Reference: http://php.net/manual/en/migration70.incompatible.php#migration70.incompatible.other.sort-order – mickmackusa Oct 26 '18 at 13:40
0

You're not saving the output: $final_keys is a regular variable being repopulated. or an array being repopulated in its case

$final_keys = array() ;
for($y=0;$y<sizeOf($sorted);$y++) {
$final_keys[] = array_keys($unsorted,$sorted[$y]);
//$final[] = $final_two[$y];
 }
print_r($final_keys);

you can also add each array to $final_keys the proper key:

$final_keys = array() ;
for($y=0;$y<sizeOf($sorted);$y++) {
$final_keys[$y] = array_keys($unsorted,$sorted[$y]);
//$final[] = $final_two[$y];
 }
print_r($final_keys);
Guy Louzon
  • 1,175
  • 9
  • 19
0

Try this simple solution using array_search()

$unsorted = [1,2,1,14,3,1,3,6,1,13,83,4, 4 ,68];
$sorted = [83,68,14,13,6,4,4,3,3,2,1,1,1,1];

foreach($sorted as $value) {
    $final_keys[] = $tempKey = array_search($value,$unsorted);
    unset($unsorted[$tempKey]);
}
print_r($final_keys);
Sachin
  • 789
  • 5
  • 18
0

Because array_search is a slow operation, using results in quadratic complexity. Instead, you can use linear complexity by making two passes through the array.

$unsorted = [1,2,1,14,3,1,3,6,1,13,83,4, 4 ,68];
$sorted = [83,68,14,13,6,4,4,3,3,2,1,1,1,1];

$temp = [];
foreach($unsorted as $k=>$v) {
    $temp[$v][] = $k;
}

$res = [];
foreach($sorted as $v) {
    $res[] = array_shift($temp[$v]);
}

print_r($res);

demo

splash58
  • 26,043
  • 3
  • 22
  • 34