Tell me more ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

I want to sort all php arrays based on first main array.

This is the main array which I want to use to sort all other arrays:

Array (

[0] => 10
[1] => 14
[2] => 15
[3] => 20
[4] => 21
[5] => 24
[6] => 25
[7] => 28
[8] => 30
[9] => 45
[10] => 60
[11] => 90
[12] => 120
[13] => 150
[14] => 180
[15] => 210
[16] => 240
[17] => 270
[18] => 365

)

This are arrays which need to be sorted :

Array (

[0] => Array
    (
        [14] => 49.21
        [20] => 71.04
        [25] => 89.58
        [30] => 100.00
    )

[1] => Array
    (
        [180] => 412.00
        [150] => 347.00
        [120] => 285.00
        [90] => 224.00
        [60] => 165.00
        [30] => 100.00
        [14] => 47.00
    )

)

I need that final result look like this:

Array (

[0] => Array
    (
        [10] => n/a
        [14] => 49.21
        [15] => n/a
        [20] => 71.04
        [21] => n/a
        [24] => n/a
        [25] => 89.58
        [28] => n/a
        [30] => 100.00
        [45] => n/a
        [60] => n/a
        [90] => n/a
        [120] => n/a
        [150] => n/a
        [180] => n/a
        [210] => n/a
        [240] => n/a
        [270] => n/a
        [365] => n/a
    )

[1] => Array
    (
        [10] => n/a
        [14] => 71.04
        [15] => n/a
        [20] => n/a
        [21] => n/a
        [24] => n/a
        [25] => n/a
        [28] => n/a
        [30] => 100.00
        [45] => n/a
        [60] => 165.00
        [90] => 224.00
        [120] => 285.00
        [150] => 347.00
        [180] => 412.00
        [210] => n/a
        [240] => n/a
        [270] => n/a
        [365] => n/a
    )

    )

Thanks.

share|improve this question
1  
"Shorted"? Sorted? – deceze Jul 28 '11 at 14:49
Does not exactly look like sorting to me. Can you explain what you want to do? To me it looks like filling the array with unused keys and then sorting by this keys (which could be done by ksort) – Nobody Jul 28 '11 at 14:56

2 Answers

up vote 0 down vote accepted

If I understand it right from your question, you want to make both arrays of the same length and set keys not in them to "n/a".

Variant with array_merge (Demo):

$shorten = array(
  0 => 10,
  1 => 14,
  2 => 15,
  3 => 20,
  4 => 21,
  5 => 24,
  6 => 25,
  7 => 28,
  8 => 30,
  9 => 45,
  10 => 60,
  11 => 90,
  12 => 120,
  13 => 150,
  14 => 180,
  15 => 210,
  16 => 240,
  17 => 270,
  18 => 365,
);

$data = array(
  0 => array(
    14 => '49.21',
    20 => '71.04',
    25 => '89.58',
    30 => '100.00',
  ),
  1 => array(
    180 => '412.00',
    150 => '347.00',
    120 => '285.00',
    90 => '224.00',
    60 => '165.00',
    30 => '100.00',
    14 => '47.00',
  ),
);

// default array as the base
$shorten = array_combine($shorten, array_fill(0, count($shorten), 'n/a'));

foreach($data as &$array) {
    // merge to get set members
    $array = array_merge($shorten, $array);
}
unset($array);

var_dump($data);

Result:

array(2) {
  [0]=>
  array(23) {
    [0]=>
    string(3) "n/a"
    [1]=>
    string(3) "n/a"
    [2]=>
    string(3) "n/a"
    [3]=>
    string(3) "n/a"
    [4]=>
    string(3) "n/a"
    [5]=>
    string(3) "n/a"
    [6]=>
    string(3) "n/a"
    [7]=>
    string(3) "n/a"
    [8]=>
    string(3) "n/a"
    [9]=>
    string(3) "n/a"
    [10]=>
    string(3) "n/a"
    [11]=>
    string(3) "n/a"
    [12]=>
    string(3) "n/a"
    [13]=>
    string(3) "n/a"
    [14]=>
    string(3) "n/a"
    [15]=>
    string(3) "n/a"
    [16]=>
    string(3) "n/a"
    [17]=>
    string(3) "n/a"
    [18]=>
    string(3) "n/a"
    [19]=>
    string(5) "49.21"
    [20]=>
    string(5) "71.04"
    [21]=>
    string(5) "89.58"
    [22]=>
    string(6) "100.00"
  }
  [1]=>
  array(26) {
    [0]=>
    string(3) "n/a"
    [1]=>
    string(3) "n/a"
    [2]=>
    string(3) "n/a"
    [3]=>
    string(3) "n/a"
    [4]=>
    string(3) "n/a"
    [5]=>
    string(3) "n/a"
    [6]=>
    string(3) "n/a"
    [7]=>
    string(3) "n/a"
    [8]=>
    string(3) "n/a"
    [9]=>
    string(3) "n/a"
    [10]=>
    string(3) "n/a"
    [11]=>
    string(3) "n/a"
    [12]=>
    string(3) "n/a"
    [13]=>
    string(3) "n/a"
    [14]=>
    string(3) "n/a"
    [15]=>
    string(3) "n/a"
    [16]=>
    string(3) "n/a"
    [17]=>
    string(3) "n/a"
    [18]=>
    string(3) "n/a"
    [19]=>
    string(6) "412.00"
    [20]=>
    string(6) "347.00"
    [21]=>
    string(6) "285.00"
    [22]=>
    string(6) "224.00"
    [23]=>
    string(6) "165.00"
    [24]=>
    string(6) "100.00"
    [25]=>
    string(5) "47.00"
  }
}

Variant with mapping function (Demo):

$shorten = array(
  0 => 10,
  1 => 14,
  2 => 15,
  3 => 20,
  4 => 21,
  5 => 24,
  6 => 25,
  7 => 28,
  8 => 30,
  9 => 45,
  10 => 60,
  11 => 90,
  12 => 120,
  13 => 150,
  14 => 180,
  15 => 210,
  16 => 240,
  17 => 270,
  18 => 365,
);

// overload $shorten array with a mapping function
$shorten = function(array $a) use ($shorten)
{
    $r = array();
    foreach($shorten as $i => $k)
    {
        $r[$k] = isset($a[$k]) ? $a[$k] : 'n/a';
    }
    return $r;
};


$data = array(
  0 => array(
    14 => '49.21',
    20 => '71.04',
    25 => '89.58',
    30 => '100.00',
  ),
  1 => array(
    180 => '412.00',
    150 => '347.00',
    120 => '285.00',
    90 => '224.00',
    60 => '165.00',
    30 => '100.00',
    14 => '47.00',
  ),
);

// apply mapping function to $data
$data = array_map($shorten, $data);

var_dump($data); # result

Result:

array(2) {
  [0]=>
  array(19) {
    [10]=>
    string(3) "n/a"
    [14]=>
    string(5) "49.21"
    [15]=>
    string(3) "n/a"
    [20]=>
    string(5) "71.04"
    [21]=>
    string(3) "n/a"
    [24]=>
    string(3) "n/a"
    [25]=>
    string(5) "89.58"
    [28]=>
    string(3) "n/a"
    [30]=>
    string(6) "100.00"
    [45]=>
    string(3) "n/a"
    [60]=>
    string(3) "n/a"
    [90]=>
    string(3) "n/a"
    [120]=>
    string(3) "n/a"
    [150]=>
    string(3) "n/a"
    [180]=>
    string(3) "n/a"
    [210]=>
    string(3) "n/a"
    [240]=>
    string(3) "n/a"
    [270]=>
    string(3) "n/a"
    [365]=>
    string(3) "n/a"
  }
  [1]=>
  array(19) {
    [10]=>
    string(3) "n/a"
    [14]=>
    string(5) "47.00"
    [15]=>
    string(3) "n/a"
    [20]=>
    string(3) "n/a"
    [21]=>
    string(3) "n/a"
    [24]=>
    string(3) "n/a"
    [25]=>
    string(3) "n/a"
    [28]=>
    string(3) "n/a"
    [30]=>
    string(6) "100.00"
    [45]=>
    string(3) "n/a"
    [60]=>
    string(6) "165.00"
    [90]=>
    string(6) "224.00"
    [120]=>
    string(6) "285.00"
    [150]=>
    string(6) "347.00"
    [180]=>
    string(6) "412.00"
    [210]=>
    string(3) "n/a"
    [240]=>
    string(3) "n/a"
    [270]=>
    string(3) "n/a"
    [365]=>
    string(3) "n/a"
  }
}
share|improve this answer
Thanks works as I wanted. – gt29 Jul 28 '11 at 15:11

Assuming your initial array is $source, and $todo is your second array with the two subsets, then:

$keys = array_flip($todo);
$keys = array_map(function() { return 'n/a'; }, $keys); // set all values to be "n/a";

foreach($todo as $idx => $do) {
   $todo[$idx] = $do + $keys; // merge without renumbering.
}
share|improve this answer
I thought about array union as well, but the key-order of $todo is not preserved, it's added behind. Must not be an issue anyway. – hakre Jul 28 '11 at 15:17
true enough, but easy enough to ksort() it afterwards if it becomes an issue. – Marc B Jul 28 '11 at 15:23

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.