phpsetsubset

Finding sub set of given set (array) by certain rule (php)


I have following problem:

I have list (array) of items, and each of item belongs to category. I have rules that say which of 2 categories can go together. I have method get_rule_by_item(itemId1,itemId2) that returns true if categories of given items can be grouped together, and false if they can't.

So I need to write PHP code to group an array of items into best matched groups by mentioned rule.

Array
(
    [tQVcIqz] => Array
        (
            [id] => tQVcIqz
            [data] => Array
                (
                    [orderId] => tQVcIqz
                    [createdOn] => 2013-09-30 01:44:46
                    [status] => nije placeno
                    [total] => 2631.00
                )

            [item_data] => Array
                (
                    [0] => Array
                        (
                            [name] => Item 1 - 1
                            [code] => ITEM1-123
                            [qty] => 1
                            [price] => 12
                        )

                    [1] => Array
                        (
                            [name] => Item 2 -2 
                            [code] => ITEM2-123
                            [qty] => 2
                            [price] => 123
                        )

                    [2] => Array
                        (
                            [name] => Item 3 - 3
                            [code] => ITEM3-123
                            [qty] => 3
                            [price] => 12
                        )

                    [3] => Array
                        (
                            [name] => Item 4 - 4
                            [code] => ITEM4-4
                            [qty] => 4
                            [price] => 123
                        )

                    [4] => Array
                        (
                            [name] => Item 5 - 5
                            [code] => ITEM5-123
                            [qty] => 5
                            [price] => 123
                        )

                )

        )

)

this is input array... item data is that array that needs to be split in different subsets... for example here, set of rules is like this :

item1 item2 rule
 1      2     1
 1      3     0 
 1      4     1 
 1      5     1
 4      5     0

where rule is 1 - if they can go together and 0 if they cant...

And ids of items are starting from 1 , just indexes in array start from 0...


Solution

  • Assuming that $res gets the array like I posted in the question:

    function group_ok($code, $group) {
        if (!is_array($group)) return TRUE;
        foreach($group as $item){
            if ($this->get_rules_items($code, $item) === FALSE) return FALSE;}
        return TRUE;
    }
    
    function remove($arr,$val){
        if(($key = array_search($val, $arr)) !== false) {
            unset($arr[$key]);
        }
        return $arr;
    }
    
    
    function get_user_orders(){
        $userId = $this->tank_auth->get_user_id();
        
        $res = $this->shop->get_orders_by_user($userId);
        
        foreach($res as $key => $val){
            $it = array();
            foreach($val['item_data'] as $items) $it[] = $items['id'];
        }
    
        $k=0;
        $group = array();
    
        while(sizeof($it)>0){
            foreach($it as $item){
                
                if($this->group_ok($item,$group[$k])){
                    $group[$k][] = $item;
                    $it = $this->remove($it,$item);
                
                }
            }
            
            $k++;
        }