0

Hi I have an array like the following:

$originalArray = [
    'Furniture/Fixture' => [
        [
            'LedgerId' => '557af7adc3acc3ac2b8b4567',
            'groupName' => 'Furniture/Fixture',
            'weightage' => 29,
            'ledgerName' => 'Furniture & Fixture',
        ],
        [
            'LedgerId' => '558ffa02c3acc331258b4567',
            'groupName' => 'Furniture/Fixture',
            'weightage' => 28,
            'ledgerName' => 'Water Coolers,Referigerator',
        ],
    ],
    'Building' => [
        [
            'LedgerId' => '5586c5eec3acc3f42c8b4567',
            'groupName' => 'Building',
            'weightage' => 26,
            'ledgerName' => 'Main Building',
        ],
        [
            'LedgerId' => '5586c85cc3acc38e2e8b4567',
            'groupName' => 'Building',
            'weightage' => 22,
            'ledgerName' => 'Jr.School Building',
        ],
    ],
    'Vehicle' => [
        [
            'LedgerId' => '55898004c3acc38b758b4567',
            'groupName' => 'Vehicle',
            'weightage' => 37,
            'ledgerName' => 'School Bus',
        ],
        [
            'LedgerId' => '55898078c3acc3c5758b4567',
            'groupName' => 'Vehicle',
            'weightage' => 27,
            'ledgerName' => 'Staff Car - TATA Mobile',
        ],
    ],
    'Plant & Machinery' => [
        [
            'LedgerId' => '557af81fc3acc3ed2b8b4567',
            'groupName' => 'Plant & Machinery',
            'weightage' => 18,
            'ledgerName' => 'Tools For Carpentres',
        ],
        [
            'LedgerId' => '557afff7c3acc38d2e8b4567',
            'groupName' => 'Plant & Machinery',
            'weightage' => 29,
            'ledgerName' => 'Water Heating Equipment',
        ],
        [
            'LedgerId' => '557b004dc3acc3bf2e8b4567',
            'groupName' => 'Plant & Machinery',
            'weightage' => 28,
            'ledgerName' => 'Mess Cold Room',
        ],
    ],
];

I want to sort each associative array, like Furniture/Fixture and Buildings, using the key inside each array weightage. How can I solve it, so that the output looks like this?

Array
([Building] => Array
    (
        [0] => Array
            (
                [LedgerId] => 5586c5eec3acc3f42c8b4567
                [groupName] => Building
                [weightage] => 26
                [ledgerName] => Main Building
            )

        [1] => Array
            (
                [LedgerId] => 5586c85cc3acc38e2e8b4567
                [groupName] => Building
                [weightage] => 26
                [ledgerName] => Jr.School Building
            )
    )
[Vehicle] => Array
    (
        [0] => Array
            (
                [LedgerId] => 55898004c3acc38b758b4567
                [groupName] => Vehicle
                [weightage] => 27
                [ledgerName] => School Bus
            )

        [1] => Array
            (
                [LedgerId] => 55898078c3acc3c5758b4567
                [groupName] => Vehicle
                [weightage] => 27
                [ledgerName] => Staff Car - TATA Mobile
            )            

    )
[Plant & Machinery] => Array
    (
        [0] => Array
            (
                [LedgerId] => 557af81fc3acc3ed2b8b4567
                [groupName] => Plant & Machinery
                [weightage] => 28
                [ledgerName] => Tools For Carpentres
            )

        [1] => Array
            (
                [LedgerId] => 557afff7c3acc38d2e8b4567
                [groupName] => Plant & Machinery
                [weightage] => 28
                [ledgerName] => Water Heating Equipment
            )


    )
[Furniture/Fixture] => Array
    (
        [0] => Array
            (
                [LedgerId] => 557af7adc3acc3ac2b8b4567
                [groupName] => Furniture/Fixture
                [weightage] => 29
                [ledgerName] => Furniture & Fixture
            )

        [1] => Array
            (
                [LedgerId] => 558ffa02c3acc331258b4567
                [groupName] => Furniture/Fixture
                [weightage] => 29
                [ledgerName] => Water Coolers,Referigerator
            )  

    )    

)

Thanks in advance.

Ali
  • 2,993
  • 3
  • 19
  • 42
Sunil Rawat
  • 709
  • 10
  • 41
  • You could use PHP's [`usort()`](http://php.net/manual/en/function.usort.php) method. would be great if you could correct your sample format as well :) – Ali Jul 17 '15 at 07:26

2 Answers2

0

You could use the usort function, passing a callback, like this:

function compare($array1, $array2) {

    $a = $array1['weightage'];
    $b = $array2['weightage'];

    if ($a < $b) {
        return -1;
    }
    elseif($b < $a) {
        return 1;
    }

    return 0;
}

$result = usort($originalArray, "compare");
PachinSV
  • 3,680
  • 2
  • 29
  • 41
0

Thanks for reformating the code :) here is the usort method which does the job

$sortedArray = usort($originalArray, function($firstItem, $secondItem){
    return $firstItem['weightage'] < $secondItem['weightage'];
});

or if you don't prefer to use anonymous function :

function sortByWeightage($firstItem, $secondItem)
{
    return $firstItem['weightage'] < $secondItem['weightage'];
}

$sortedArray = usort($originalArray, "sortByWeihtage");

here is a functions snippet, using the provided sample data (well I've changed the 'weightage' values to demonstrate reordering, and applied the same to the question):

<?php

$originalArray = [
    'Furniture/Fixture' => [
        [
            'LedgerId' => '557af7adc3acc3ac2b8b4567',
            'groupName' => 'Furniture/Fixture',
            'weightage' => 29,
            'ledgerName' => 'Furniture & Fixture',
        ],
        [
            'LedgerId' => '558ffa02c3acc331258b4567',
            'groupName' => 'Furniture/Fixture',
            'weightage' => 28,
            'ledgerName' => 'Water Coolers,Referigerator',
        ],
    ],
    'Building' => [
        [
            'LedgerId' => '5586c5eec3acc3f42c8b4567',
            'groupName' => 'Building',
            'weightage' => 26,
            'ledgerName' => 'Main Building',
        ],
        [
            'LedgerId' => '5586c85cc3acc38e2e8b4567',
            'groupName' => 'Building',
            'weightage' => 22,
            'ledgerName' => 'Jr.School Building',
        ],
    ],
    'Vehicle' => [
        [
            'LedgerId' => '55898004c3acc38b758b4567',
            'groupName' => 'Vehicle',
            'weightage' => 37,
            'ledgerName' => 'School Bus',
        ],
        [
            'LedgerId' => '55898078c3acc3c5758b4567',
            'groupName' => 'Vehicle',
            'weightage' => 27,
            'ledgerName' => 'Staff Car - TATA Mobile',
        ],
    ],
    'Plant & Machinery' => [
        [
            'LedgerId' => '557af81fc3acc3ed2b8b4567',
            'groupName' => 'Plant & Machinery',
            'weightage' => 18,
            'ledgerName' => 'Tools For Carpentres',
        ],
        [
            'LedgerId' => '557afff7c3acc38d2e8b4567',
            'groupName' => 'Plant & Machinery',
            'weightage' => 29,
            'ledgerName' => 'Water Heating Equipment',
        ],
        [
            'LedgerId' => '557b004dc3acc3bf2e8b4567',
            'groupName' => 'Plant & Machinery',
            'weightage' => 28,
            'ledgerName' => 'Mess Cold Room',
        ],
    ],
];

echo 'Printing original array BEFORE being sorted' . PHP_EOL;
print_r($originalArray);

foreach ($originalArray as &$group) {

    $sortedGroup = usort($group, function($firstItem, $secondItem){
        return $firstItem['weightage'] > $secondItem['weightage'];
    });

}

echo 'Printing original array AFTER being sorted' . PHP_EOL;
print_r($originalArray);

UPDATE:

If you need to order groups and not group elements (as per our conversation bellow) then you could remove the loop and amend the usort as followed:

$sortedGroup = usort($originalArray, function($firstItem, $secondItem){
    return $firstItem[0]['weightage'] > $secondItem[0]['weightage'];
});  

But again as suggested earlier its not the best data structure to have the group order in all of the groups element, if you have control over it consider to reformat it to something like :

$originalArray = [
    'Furniture/Fixture' => [
        'weightage' => 100,
        'items' => [
            [
                'LedgerId' => '557af7adc3acc3ac2b8b4567',
                'groupName' => 'Furniture/Fixture',
                'ledgerName' => 'Furniture & Fixture',
            ],
            [
                'LedgerId' => '558ffa02c3acc331258b4567',
                'groupName' => 'Furniture/Fixture',
                'ledgerName' => 'Water Coolers,Referigerator',
            ],
        ]
    ],
......

and use a unique specific key for sorting them

Ali
  • 2,993
  • 3
  • 19
  • 42
  • Here first and secod item is same key.. So how to call it inside a loop.. – Sunil Rawat Jul 17 '15 at 07:50
  • how to pass $firstItem, $secondItem variables. Please help me.. – Sunil Rawat Jul 17 '15 at 07:54
  • `usort` will pass them for you, give me a sec, i'm formatting your sample arrays to put them all together to demonstrate covering the second level of nesting as well – Ali Jul 17 '15 at 07:54
  • ok Please.. thanks lot – Sunil Rawat Jul 17 '15 at 07:59
  • Most welcome, if it was helpful please don't forget to accept the answer :) – Ali Jul 17 '15 at 08:10
  • But it is not sorting the array.. output is same like before sort.. Giving array in same order like before. – Sunil Rawat Jul 17 '15 at 08:43
  • $sortedGroup = usort($group, function($firstItem, $secondItem){ return $firstItem['weightage'] > $secondItem['weightage']; }); //It return 1 every time and pusd that 1 into array $sortedArray. How it will work not not possible $sortedArray[] = $sortedGroup; – Sunil Rawat Jul 17 '15 at 08:47
  • Consider that "1" as true , it is the boolean return value which [usort](http://php.net/manual/en/function.usort.php) expects from its `value_compare_func` call back – Ali Jul 17 '15 at 08:52
  • Yes, but it not sorting the array new array is same as it was before. Can you please run this code to check.. Thanks lot – Sunil Rawat Jul 17 '15 at 08:55
  • 'Furniture/Fixture' => [ [ 'LedgerId' => '557af7adc3acc3ac2b8b4567', 'groupName' => 'Furniture/Fixture', 'weightage' => 29, 'ledgerName' => 'Furniture & Fixture', ], [ 'LedgerId' => '558ffa02c3acc331258b4567', 'groupName' => 'Furniture/Fixture', 'weightage' => 28, 'ledgerName' => 'Water Coolers,Referigerator', ], ] For One Single Key Like : ['Furniture/Fixture'] weightage will be same like 28 and for another key ['Building'] again weighatge will be same like 27. – Sunil Rawat Jul 17 '15 at 09:05
  • I see whats the reason for the confusion :) have a read on [`usrot`](http://php.net/manual/en/function.usort.php). the "1" you are talking about is actually a boolean `true`. `usort` receives the array by [reference](http://php.net/manual/en/language.references.pass.php) which means it will modify the original array (`$group` in this case). now pay attention to our `foreach` loop which iterates on the original (main) array but again using `reference` (**&** in &$group). – Ali Jul 17 '15 at 09:09
  • this my code: echo 'Printing original array BEFORE being sorted'; echo "
    "; print_r($result);
           
    
            foreach ($result as $group) {
    
                $sortedGroup = usort($group, function($firstItem, $secondItem){
                    return $firstItem['weightage'] > $secondItem['weightage'];
                });
    
                $sortedArray[] = $sortedGroup;
                
            }
    
            echo 'Printing original array AFTER being sorted' ;
           echo "
    "; print_r($result);die;  So is there anything else need to check inside foreach loop to output array sorted order.?
    – Sunil Rawat Jul 17 '15 at 09:14
  • ahhh, i see, you don't want to sort each group, you want to sort groups in the main array. right ? – Ali Jul 17 '15 at 09:15
  • Yes you are right... Supose key [''Furniture/Fixture''] has weightage "26". it should come first the another like ['Buildings'] after it if it has weightage "27". etc.. – Sunil Rawat Jul 17 '15 at 09:16
  • if so, then you don't need the loop just use `$sortedGroup = usort($originalArray, function($firstItem, $secondItem){ return $firstItem[0]['weightage'] > $secondItem[0]['weightage']; });` i will include this to my answer but also i would suggest to change the array structure if you have control over it, to add the ordering factor only once for the group instead of having it for each of the group elements – Ali Jul 17 '15 at 09:20
  • ok Please add it to your above code snipt. – Sunil Rawat Jul 17 '15 at 09:23
  • Thanks Buddy. its working now.. thanks lot. your help is appreciated.. Your Suggestion and way is very nice.. – Sunil Rawat Jul 17 '15 at 09:40
  • Your most welcome :) – Ali Jul 17 '15 at 09:44
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/83542/discussion-between-ali-and-user3458514). – Ali Jul 17 '15 at 12:18
  • Hi @user3458514, it would be great if you could up-vote my answer if it was helpful :) thanks – Ali Aug 16 '15 at 19:33