【问题标题】:Merge array if element match - algorithm如果元素匹配则合并数组 - 算法
【发布时间】:2014-08-03 05:23:16
【问题描述】:

我在不同的商店中有一系列设备(ibm、sony、dell)(以简化商店 1、2、3)。我要做的是创建一个拥有所有产品的商店的比较。在下面的示例中,唯一符合条件的商店是 shop_id: 2(商店 1 没有戴尔,商店 3 没有出售 ibm)。

例子:

[
    [  {"id": "1", "name": "ibm", "price": "22", "shop_id": "1"}, {"id": "2", "name": "ibm", "price": "27", "shop_id": "1"}, {"id": "3", "name": "ibm", "price": "21", "shop_id":" 2"} ],
    [  {"id": "4", "name": "sony", "price": "19", "shop_id": "1"}, {"id": "5", "name": "sony", "price": "21", "shop_id": "2"}, {"id": "6", "name": "sony", "price": "28", "shop_id": "3"} ],
    [  {"id": "7", "name": "dell", "price": "22", "shop_id": "2"}, {"id": "8", "name": "dell", "price": "27", "shop_id": "2"}, {"id": "9", "name": "dell", "price": "21", "shop_id": "3"} ]
]

必须转换为:

[
    [ {"id": "3", "name": "ibm", "price": "21", "shop_id": "2"}, {"id": "5", "name": "sony", "price": "21", "shop_id": "2"}, {"id": "7", "name": "dell", "price": "22", "shop_id": "2"}],
    [ {"id": "3", "name": "ibm", "price": "21", "shop_id": "2"}, {"id": "5", "name": "sony", "price": "21", "shop_id": "2"}, {"id": "8", "name": "dell", "price": "27", "shop_id": "2"}]  
]

我必须用 PHP 来做,但我只需要一个算法来解决这个问题。 有无限数量的设备 - 目前只有 3 家商店,但可能更多,所以假设它也是无限的。

到目前为止,我几乎可以使用...但是当一家商店中的设备交易超过一笔时,它就会中断(它只获得第一笔交易)。

public function getDeals($prices){

    // define return array
    $multi_deals = array();

    // get number of devices 
    $no_devices = count($prices);

    // loop over each deal for first device
    foreach ($prices[0] as $dd){
        // reset other arrays
        for ($j=1; $j<$no_devices; $j++)
            reset($prices[$j]);

        // remember deal shop
        $shop = $dd['shop_id'];
        $success = true;
        $i=0;

        // remember deal
        $multi_deal = array();
        $multi_deal[$i] = $dd;

        // loop over rest of the devices 
        while ($i < ($no_devices-1)){
            $i++;
            // only continue if found a deal from the same shop
            if ( !($multi_deal[$i] = self::getDevice($shop, $prices[$i]))){
                $success = false;
                break;
            }    

            // THIS IS WHERE PRICES ARRAY WILL BE RESET IF THE SAME DEVICE IS TWICE IN ONE SHOP        
        }

        // we looped over all devices and find deals for each one of them
        if ($success)
            $multi_deals[] = $multi_deal;
    }
}
public function getDevice($current_shop, &$deals){
    while ($deal = next($deals)){
        if ($deal['shop_id'] == $current_shop)
            return $deal;
    }
    return false;
}

我现在花了几个小时来解决这个问题,所以我会很感激任何线索。

更新:

假设您有供应商(商店)销售产品(ibm、sony、dell)。作为客户,我想购买 1*ibm + 1*sony + 1*dell,而且必须来自一家商店。

作为结果,我需要显示可能交易的完整列表,按商店划分

在我给出的示例中,只有一家商店拥有所有免费产品 - shop_id: 2。 更重要的是这家商店有2个戴尔优惠。这就是为什么我们有两个结果集,因为有两种可能的组合。

更新 2:

我尝试了不同的方法,我想我越来越接近了。我已经到了我有的地步

[
    { "shop_id": "2", "deals": [ 
        { "ibm": [ 
            {"id": "3", "name": "ibm", "price": "21", "shop_id":" 2"} 
        ] },
        { "sony": [ 
            {"id": "5", "name": "sony", "price": "21", "shop_id": "2"} 
        ] },
        { "dell": [ 
            {"id": "7", "name": "dell", "price": "22", "shop_id": "2"}, 
            {"id": "8", "name": "dell", "price": "27", "shop_id": "2"}
        ] }
    ] }
]

又要转换成:

[
    [ {"id": "3", "name": "ibm", "price": "21", "shop_id": "2"}, {"id": "5", "name": "sony", "price": "21", "shop_id": "2"}, {"id": "7", "name": "dell", "price": "22", "shop_id": "2"}],
    [ {"id": "3", "name": "ibm", "price": "21", "shop_id": "2"}, {"id": "5", "name": "sony", "price": "21", "shop_id": "2"}, {"id": "8", "name": "dell", "price": "27", "shop_id": "2"}]  
]

【问题讨论】:

  • 请澄清您的意思是“创建一个拥有所有产品的商店的比较”。在您的示例中,输入中有一个元素{id: 3, name: 'ibm', price: 21, shop_id: 2},但输出中有两个这样的元素..
  • 我真诚地为示例添加了有效的 JSON,因为这听起来是一个有趣的问题。但我有点不清楚输出应该是什么。
  • @kevinabelita 交易必须按商店拆分。如果您查看我的示例输出仅来自 shop: 2 的结果(商店 1 没有戴尔,商店 3 没有 ibm)。

标签: php arrays transformation


【解决方案1】:

哎呀,弄清楚这很有趣。特别是“扁平化”优惠数组的部分:-) 我有一个解决方案给你,不是在课堂上,但也许你可以使用它的一些元素。它非常灵活,因此您可以添加任意数量的商店和搜索项。

$search = array('ibm','sony','dell','apple');   //the words to search for
$shop=array();  


//Populate shop array with first machine    
foreach($prices[0] as $offer){
    $shop[$offer['shop_id']][0][]=$offer;
    }

//Loop trough rest of machines
$t=1;
foreach($prices as $k=>$machine){
    if($k==0)continue; //skip the first one, we've done that
    $t++;
    foreach($machine as $offer){
          //if this shop_id not exists => continue 
    if(!isset($shop[$offer['shop_id']]))continue; 
    $shop[$offer['shop_id']][$k][]=$offer; //add offer to shop
    }
foreach($shop as $id=>$v){
          //if the count of machines not right => dump this shop
    if(count($v)!=$t){
         unset($shop[$id]);
         }
    }
}
//echo '<pre>'.print_r($shop,true).'</pre>';

$shop 现在包含所有提供组合机器的商店,并且每个商店都有一系列机器报价。

//'Flatten' the shop-array, combining all possibilities     
$offers=array();
foreach($shop as $array){
    $return=array();
    foreach($array as $k=>$machine){

      //first machine: populate $return
      if($k==0){
         foreach($array[0] as $k=>$v){$return[$k][0]=$v;}
         continue;
         }

    $w=$return;
    $return=array();

    foreach($machine as $offer){
        foreach($w as $r){
        $r[]=$offer;
            $return[]=$r;
            }
        }
    }
    $offers=array_merge($offers,$return);
}

//echo '<pre>'.print_r($offers,true).'</pre>';

我用这个数组来测试:

$prices = array(
array(
array("id"=> "2", "name"=> "ibm", "price"=> "27", "shop_id"=> "11"), 
array("id"=> "3", "name"=> "ibm", "price"=> "21", "shop_id"=> "22"),
array("id"=> "10", "name"=> "ibm", "price"=> "44", "shop_id"=> "22"),
),
array(
array("id"=> "4", "name"=> "sony", "price"=> "19", "shop_id"=> "11"),
array("id"=> "5", "name"=> "sony", "price"=> "21", "shop_id"=> "22"),
array("id"=> "6", "name"=> "sony", "price"=> "28", "shop_id"=> "33"),
),
array (
array("id"=> "7", "name"=> "dell", "price"=> "22", "shop_id"=> "11"), 
array("id"=> "7", "name"=> "dell", "price"=> "44", "shop_id"=> "11"), 
array("id"=> "7", "name"=> "dell", "price"=> "22", "shop_id"=> "22"), 
array("id"=> "8", "name"=> "dell", "price"=> "27", "shop_id"=> "22"), 
array("id"=> "9", "name"=> "dell", "price"=> "21", "shop_id"=> "33")
),
array (
array("id"=> "17", "name"=> "apple", "price"=> "22", "shop_id"=> "11"), 
array("id"=> "17", "name"=> "apple", "price"=> "22", "shop_id"=> "22"), 
array("id"=> "18", "name"=> "apple", "price"=> "27", "shop_id"=> "22"), 
array("id"=> "19", "name"=> "apple", "price"=> "21", "shop_id"=> "33")
)
);

【讨论】:

  • 你是明星!如果可以的话,我会给你 10 票。非常感谢。
猜你喜欢
  • 1970-01-01
  • 2016-07-08
  • 2022-01-15
  • 1970-01-01
  • 2015-05-03
  • 2020-11-30
  • 2022-11-28
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多