0

I am creating a multidimensional array from an array that is returned from the database. Then I need to sort the array that I have created on 3 different keys. So, here is my array.

foreach($priceList->data as $obj){
    $d1d2[] = $obj->d1d2desc;
    $grade[] = $obj->grade;
    $species[] = $obj->species;
    $woodDesc[] = $obj->wooddesc;
    $prefix[] = $obj->prefix;
}

$pricing = array(
     $d1d2,
     $grade,
     $species,
     $woodDesc,
     $prefix
     );

The array works as I can use print_r or var_dump and see that I have all that I need with the array. But then I need to sort the pricing array by three of the inner arrays. First, the $d1d2, then the $grade, and then the $species.

I have tried using multisort and ksort and even msort, but I can't get anything to work. Can someone point me in the right direction?

This is the output of my print_f:

Array ( [0] => Array ( [0] => 2X10 [1] => 2X10 [2] => 2X10 [3] => 2X10 [4] => 2X12 [5] => 2X12 [6] => 2X12 [7] => 2X12 [8] => 2X4 [9] => 2X4 [10] => 2X4 [11] => 2X4 [12] => 2X4 [13] => 1X4 [14] => 1X6 [15] => 2X10 [16] => 2X10 [17] => 2X10 [18] => 2X10 [19] => 2X12 [20] => 2X12 [21] => 2X12 [22] => 2X12 [23] => 2X4 [24] => 2X4 [25] => 2X4 [26] => 2X4 [27] => 2X4 [28] => 2X6 [29] => 2X6 [30] => 2X6 [31] => 2X6 [32] => 2X6 [33] => 2X 8 [34] => 2X8 [35] => 2X 8 [36] => 2X8 [37] => 2X 8 [38] => 4X8 [39] => 4X8 [40] => 4X8 [41] => 4X8 [42] => 4X8 [43] => 4X8 [44] => 4X8 [45] => 4X8 [46] => 4X8 [47] => 4X8 [48] => 4X8 [49] => 4X8 [50] => 4X8 [51] => 4X8 [52] => 4X8 [53] => 4X8 [54] => 4X8 [55] => 4X8 [56] => 4X8 [57] => 4X8 [58] => 4X8 [59] => 4X8 [60] => 4X8 [61] => 4X8 [62] => 4X8 [63] => 4X8 [64] => 4X8 [65] => 4X8 [66] => 4X8 [67] => 4X8 [d1d2] => ) [1] => Array ( [0] => #2 [1] => #2 [2] => #2 [3] => #2 [4] => #2 [5] => #2 [6] => #2 [7] => #2 [8] => #2 [9] => #2 [10] => #2 [11] => #2 [12] => #2 [13] => [14] => [15] => #2 [16] => #2 [17] => #2 [18] => #2 [19] => #2 [20] => #2 [21] => #2 [22] => #2 [23] => #2 [24] => #2 [25] => #2 [26] => #2 [27] => #2 [28] => #2 [29] => #2 [30] => #2 [31] => #2 [32] => #2 [33] => [34] => #2 [35] => [36] => #2 [37] => [38] => [39] => [40] => [41] => [42] => [43] => [44] => [45] => [46] => [47] => [48] => [49] => [50] => [51] => [52] => [53] => [54] => [55] => [56] => [57] => [58] => [59] => [60] => [61] => [62] => [63] => [64] => [65] => [66] => [67] => [d1d2] => ) [2] => Array ( [0] => HEM FIR [1] => HEM FIR [2] => HEM FIR [3] => HEM FIR [4] => HEM FIR [5] => HEM FIR [6] => HEM FIR [7] => HEM FIR [8] => SPF [9] => SPF [10] => SPF [11] => SPF [12] => SPF [13] => SPF [14] => SPF [15] => HEM FIR [16] => HEM FIR [17] => HEM FIR [18] => HEM FIR [19] => HEM FIR [20] => HEM FIR [21] => HEM FIR [22] => HEM FIR [23] => SPF [24] => SPF [25] => SPF [26] => SPF [27] => SPF [28] => SPF [29] => SPF [30] => SPF [31] => SPF [32] => SPF [33] => SPF [34] => SPF [35] => SPF [36] => SPF [37] => SPF [38] => SYP [39] => SYP [40] => SYP [41] => SYP [42] => SYP [43] => SYP [44] => SYP [45] => SYP [46] => FIR [47] => SYP [48] => FIR [49] => SYP [50] => FIR [51] => FIR [52] => FIR [53] => FIR [54] => FIR [55] => SYP [56] => SYP [57] => SYP [58] => SYP [59] => SYP [60] => SYP [61] => SYP [62] => SYP [63] => SYP [64] => SYP [65] => SYP [66] => SYP [67] => SYP [d1d2] => ) [3] => Array ( [0] => [1] => [2] => [3] => [4] => [5] => [6] => [7] => [8] => [9] => [10] => [11] => [12] => [13] => UTILITY GRADE [14] => UTILITY GRADE [15] => [16] => [17] => [18] => [19] => [20] => [21] => [22] => [23] => [24] => [25] => [26] => [27] => [28] => [29] => [30] => [31] => [32] => [33] => [34] => [35] => [36] => [37] => [38] => RSH 4-PLY [39] => RSH [40] => RSH [41] => BCX [42] => RSH 4-PLY [43] => RSH [44] => RSH [45] => S/F T&G [46] => RSH 4-PLY [47] => RSH 4-PLY [48] => RSH 4-PLY [49] => RSH [50] => RSH [51] => RSH [52] => ACX [53] => ACX [54] => ACX [55] => ACX [56] => ACX [57] => ACX [58] => BCX [59] => BCX [60] => BCX [61] => RSH 4-PLY [62] => RSH [63] => RSH [64] => RSH 4-PLY [65] => RSH [66] => RSH [67] => S/F T&G [d1d2] => ) [4] => Array ( [0] => [1] => [2] => [3] => [4] => [5] => [6] => [7] => [8] => [9] => [10] => [11] => [12] => [13] => [14] => [15] => [16] => [17] => [18] => [19] => [20] => [21] => [22] => [23] => [24] => [25] => [26] => [27] => [28] => [29] => [30] => [31] => [32] => [33] => [34] => [35] => [36] => [37] => [38] => [39] => [40] => [41] => [42] => [43] => [44] => [45] => [46] => FSC MIXED CR [47] => [48] => [49] => [50] => [51] => [52] => [53] => [54] => [55] => [56] => [57] => [58] => [59] => [60] => [61] => FSC MIXED CR [62] => FSC MIXED CR [63] => FSC MIXED CR [64] => [65] => [66] => [67] => [d1d2] => ) )

When I try to sort it, I get no change. I deleted the multisort method that I was using and tried something else which didn't work either. So, I don't have it any longer to include the code for it as well..

halfer
  • 19,824
  • 17
  • 99
  • 186
trouble706
  • 48
  • 3
  • 15
  • 1
    The question is not clear. "I need to sort the pricing array" --- `$pricing` array is just a placeholder for several other arrays, how is it supposed to be sorted? – zerkms Dec 03 '14 at 21:35
  • 1
    This sounds like a case for [usort](http://php.net/manual/en/function.usort.php). It lets you define the sort function. Nothing in vanilla PHP will know how to juggle multiple properties. – stakolee Dec 03 '14 at 21:35
  • Could you show examples of how you implemented the multisort? Sounds to me that you have the save problem as in the following question: http://stackoverflow.com/questions/3232965/sort-multidimensional-array-by-multiple-keys – Edwin Dec 03 '14 at 21:35
  • give us the `print_r`, and then order it how you would like and give us that as well – cmorrissey Dec 03 '14 at 21:35
  • So, how *exactly* do you want it sorted. Currently, `$pricing` contains 5 items. In which order do you desire these 5 items? – gen_Eric Dec 03 '14 at 21:48
  • @RocketHazmat d1d2, grade, species, wooddescr, prefix – trouble706 Dec 03 '14 at 21:49
  • @trouble706: That's the order they are *currently* in. How do you want it to look when it's sorted? Do you want to sort `$pricing` itself or do you want to sort the contents of `$pricing[0]`? Can you try to explain what you want the final result to look like? – gen_Eric Dec 03 '14 at 21:50
  • I guess I wasn't clear... My apologies... I need the values of the inner arrays to be sorted ... For example, I need all of d1d2 to be sorted by dimension from smallest to largest. Then, as a second sort if there are duplicates, I need the grade values to be sorted next, then in case of duplicates, I need the species values to be sorted... – trouble706 Dec 03 '14 at 21:58
  • Why not just sort the arrays on their own before putting them into `$pricing`? Also, what do you mean by "in case of duplicates"? Are these arrays related to each other in some way? – gen_Eric Dec 03 '14 at 22:00
  • They are related which is why I can't sort them before putting them into pricing... These are elements of a pricing chart. – trouble706 Dec 03 '14 at 22:02
  • So, does the order of `$grade` and `$species` need to match that of `$d1d2`? Let's go further back... what's `$priceList`? Can these values be sorted back then? Maybe back in the SQL query or wherever they came from? – gen_Eric Dec 03 '14 at 22:04
  • That would be nice... But I don't actually make the sql query or that is what I would do.. This uses a pre-written library for accessing the db. I don't have access to it. Pricelist is simply the array that is returned from the db. I guess it could be sorted there.. It kind of works as a SELECT * would so there is a lot of data that is being returned that I have no need for... That is why I was attempting to do this differently.. – trouble706 Dec 03 '14 at 22:09

2 Answers2

2

Are you sure the array_multisort doesn't work?

array_multisort(
        $pricing->d1d2, SORT_ASC, SORT_NUMERIC,
        $pricing->grade, SORT_ASC, SORT_NUMERIC,
        $pricing->species, SORT_ASC, SORT_NUMERIC
);

or

array_multisort(
        $pricing[0], SORT_ASC, SORT_NUMERIC,
        $pricing[1], SORT_ASC, SORT_NUMERIC,
        $pricing[2], SORT_ASC, SORT_NUMERIC
);

EDIT

So much time without coding PHP and I miss that array_multisort must included all the members:

array_multisort(
        $pricing[0], SORT_ASC, SORT_NUMERIC,
        $pricing[1], SORT_ASC, SORT_NUMERIC,
        $pricing[2], SORT_ASC, SORT_NUMERIC,
        $pricing[3], SORT_ASC, SORT_NUMERIC,
        $pricing[4], SORT_ASC, SORT_NUMERIC
);

UPDATE

These are the sorting type supported by array_multisort:

SORT_REGULAR - Default. Compare elements normally (Standard ASCII)

SORT_NUMERIC - Compare elements as numeric values

SORT_STRING - Compare elements as string values

SORT_LOCALE_STRING - Compare elements as string, based on the current locale (can be changed using setlocale())

SORT_NATURAL - Compare elements as strings using "natural ordering" like natsort()

SORT_FLAG_CASE - Can be combined (bitwise OR) with SORT_STRING or SORT_NATURAL to sort strings case-insensitively

Verhaeren
  • 1,661
  • 9
  • 10
  • I think `$pricing->d1d2` and so on must be replaced by `$pricing[0]` and so on. Check it now. – Verhaeren Dec 03 '14 at 21:50
  • Tried that as well and it did change the order, but it is not sorted correctly... For example 2X4, 2X12, 2X4, 2X6... etc.. – trouble706 Dec 03 '14 at 21:53
  • 1
    Have you tried to customize it to suit your needs? Notice that you might want `SORT_DESC` instead of `SORT_ASC` or `SORT_STRING` instead of `SORT_NUMERIC`. – Verhaeren Dec 03 '14 at 21:57
  • I tried changing them and I noticed something... I have 2X10, 2X12, showing up before 2X4, 2X6, 2X8 now... So, I am wondering if the double digit (10, 12) is throwing the sort off? – trouble706 Dec 03 '14 at 22:05
  • I think I got it. Check my answer now. – Verhaeren Dec 03 '14 at 22:09
  • I had already thought of that and so tried it... That is when I made my comment above. – trouble706 Dec 03 '14 at 22:16
  • @Verhaeren: I think he needs `SORT_NATURAL` because his values are like `2X10`. – gen_Eric Dec 03 '14 at 22:18
  • Now that is weird.. I can't get it to work. It still doesn't hold the correct order.. – trouble706 Dec 03 '14 at 22:19
  • @RocketHazmat That's on him, the `array_multisort` works that way, all elements and the parameters in that order, etc. I don't know what data is he handling. – Verhaeren Dec 03 '14 at 22:21
  • Thank you @Verhaeren. I was able to make it work with the SORT_NATURAL. – trouble706 Dec 04 '14 at 15:28
2

I've handled cases like that by writing a sort method and using usort(); it's easier for me to think of sorting as code

// sort data along 3 axes, each in increasing order
function comparData( $a, $b ) {
    if ($a->d1d2 < $b->d1d2) return -1;
    if ($a->d1d2 > $b->d1d2) return 1;
    if ($a->grade < $b->grade) return -1;
    if ($a->grade > $b->grade) return 1;
    if ($a->species < $b->species) return -1;
    if ($b->species > $b->species) return 1;
    return 0;
}

$data = $priceList->data;
usort($data, 'comparData');

That puts data into sorted order; now when you build up the separate arrays they will be built in sorted order.

Andras
  • 2,995
  • 11
  • 17