基于特定多个键的唯一多维数组

时间:2019-03-29 10:39:07

标签: php arrays

我有一个多维数组,需要根据特定的键使用唯一数组对它进行排序。 item_type_id键上的值相同,而partner_idstore_id键不同。我期望的结果是,当item_type_id键具有相同的值,并且在具有相同partner_id的不同store_id键中,它应该首先在10017上优先使用partner_id值键。

示例数组

[
    0 => [
        "partner_id" => "10017"
        "store_id" => "1000"
        "item_type_id" => "2"
        "value" => "58"
        "category" => "1"
    ]
    1 => [
        "partner_id" => "10017"
        "store_id" => "1000"
        "item_type_id" => "1"
        "value" => "63"
        "category" => "1"
    ]
    2 => [
        "partner_id" => "0"
        "store_id" => "1000"
        "item_type_id" => "3"
        "value" => "29"
        "category" => "1"
    ]
    3 => [
        "partner_id" => "0"
        "store_id" => "1000"
        "item_type_id" => "2"
        "value" => "58"
        "category" => "1"
    ]
    4 => [
        "partner_id" => "0"
        "store_id" => "1001"
        "item_type_id" => "1"
        "value" => "65"
        "category" => "1"
    ]
    5 => [
        "partner_id" => "0"
        "store_id" => "1001"
        "item_type_id" => "2"
        "value" => "58"
        "category" => "1"
    ]
    6 => [
        "partner_id" => "0"
        "store_id" => "1001"
        "item_type_id" => "3"
        "value" => "29"
        "category" => "1"
    ]
    7 => [
        "partner_id" => "0"
        "store_id" => "1000"
        "item_type_id" => "1"
        "value" => "65"
        "category" => "1"
    ]
]

结果

[
    1000 => [
        0 => [
            "partner_id" => "10017"
            "store_id" => "1000"
            "item_type_id" => "2"
            "value" => "58"
            "category" => "1"
        ]
        1 => [
            "partner_id" => "10017"
            "store_id" => "1000"
            "item_type_id" => "1"
            "value" => "63"
            "category" => "1"
        ]
        2 => [
            "partner_id" => "0"
            "store_id" => "1000"
            "item_type_id" => "3"
            "value" => "29"
            "category" => "1"
        ]
    ]

    1001 => [
        0 => [
            "partner_id" => "0"
            "store_id" => "1001"
            "item_type_id" => "1"
            "value" => "65"
            "category" => "1"
        ]
        1 => [
            "partner_id" => "0"
            "store_id" => "1001"
            "item_type_id" => "2"
            "value" => "58"
            "category" => "1"
        ]
        2 => [
            "partner_id" => "0"
            "store_id" => "1001"
            "item_type_id" => "3"
            "value" => "29"
            "category" => "1"
        ]
    ]
]

这是我的脚本

$storeID = [1000,1001];
$createdArray = [];
$previous_item_type_id = "";
$previous_partner_id = "";
foreach($arrays as $array) {
    for($i=0; $i<count($storeID); $i++) {
        if($array["store_id"] == $storeID[$i]) {
            if($array["item_type_id"] != $previous_item_type_id && $array["partner_id"] != $previous_partner_id) {
                $createdArray[$storeID[$i]] = [
                        "partner_id" => $array["partner_id"],
                        "store_id" => $array["store_id"],
                        "item_type_id" => $array["item_type_id"],
                        "value" => $array["value"],
                        "category" => $array["category"],
                    ];
            } else {
                $previous_item_type_id = $array["item_type_id"];
                $previous_partner_id = $array["partner_id"];
                continue;
            }

        }
    }
}

dd($createdArray);

2 个答案:

答案 0 :(得分:1)

您可以使用简单的foreach循环来遍历数组,然后使用子数组键store_id获取最终数组的键。将最后一个值推入当前值。

此外,要删除重复的item_type_id,我将编写一个函数来检查结果中是否已存在该ID。

例如:

$storeID = [1000,1001];

$array = [
    0 => [
        "partner_id" => "10017",
        "store_id" => "1000",
        "item_type_id" => "2",
        "value" => "58",
        "category" => "1"
    ],
    1 => [
        "partner_id" => "10017",
        "store_id" => "1000",
        "item_type_id" => "1",
        "value" => "63",
        "category" => "1",
    ],
    2 => [
        "partner_id" => "0",
        "store_id" => "1000",
        "item_type_id" => "3",
        "value" => "29",
        "category" => "1"
    ],
    3 => [
        "partner_id" => "0",
        "store_id" => "1000",
        "item_type_id" => "2",
        "value" => "58",
        "category" => "1",
    ],
    4 => [
        "partner_id" => "0",
        "store_id" => "1001",
        "item_type_id" => "1",
        "value" => "65",
        "category" => "1",
    ],
    5 => [
        "partner_id" => "0",
        "store_id" => "1001",
        "item_type_id" => "2",
        "value" => "58",
        "category" => "1",
    ],
    6 => [
        "partner_id" => "0",
        "store_id" => "1001",
        "item_type_id" => "3",
        "value" => "29",
        "category" => "1"
    ],
    7 => [
        "partner_id" => "0",
        "store_id" => "1000",
        "item_type_id" => "1",
        "value" => "65",
        "category" => "1"
    ]
];

function ItemIdExists($arr, $itemId)
{
    foreach ($arr as $subValue)
    {
        if ($subValue["item_type_id"] == $itemId)
        {
            return true;
        }
    }
    return false;
}

$result = array();
foreach ($array as $value)
{
    $key = $value["store_id"];
    if (in_array($key, $storeID))
    {
        $ItemIdFound = isset($result[$key]) && ItemIdExists($result[$key], $value["item_type_id"]);

        if (!$ItemIdFound)
            $result[$key][] = $value;
    }
}
var_dump($result);

输出

array(2) {
  [1000]=>
  array(3) {
    [0]=>
    array(5) {
      ["partner_id"]=>
      string(5) "10017"
      ["store_id"]=>
      string(4) "1000"
      ["item_type_id"]=>
      string(1) "2"
      ["value"]=>
      string(2) "58"
      ["category"]=>
      string(1) "1"
    }
    [1]=>
    array(5) {
      ["partner_id"]=>
      string(5) "10017"
      ["store_id"]=>
      string(4) "1000"
      ["item_type_id"]=>
      string(1) "1"
      ["value"]=>
      string(2) "63"
      ["category"]=>
      string(1) "1"
    }
    [2]=>
    array(5) {
      ["partner_id"]=>
      string(1) "0"
      ["store_id"]=>
      string(4) "1000"
      ["item_type_id"]=>
      string(1) "3"
      ["value"]=>
      string(2) "29"
      ["category"]=>
      string(1) "1"
    }
  }
  [1001]=>
  array(3) {
    [0]=>
    array(5) {
      ["partner_id"]=>
      string(1) "0"
      ["store_id"]=>
      string(4) "1001"
      ["item_type_id"]=>
      string(1) "1"
      ["value"]=>
      string(2) "65"
      ["category"]=>
      string(1) "1"
    }
    [1]=>
    array(5) {
      ["partner_id"]=>
      string(1) "0"
      ["store_id"]=>
      string(4) "1001"
      ["item_type_id"]=>
      string(1) "2"
      ["value"]=>
      string(2) "58"
      ["category"]=>
      string(1) "1"
    }
    [2]=>
    array(5) {
      ["partner_id"]=>
      string(1) "0"
      ["store_id"]=>
      string(4) "1001"
      ["item_type_id"]=>
      string(1) "3"
      ["value"]=>
      string(2) "29"
      ["category"]=>
      string(1) "1"
    }
  }
}

答案 1 :(得分:0)

如果我了解要求,预期的结果将:

  • 根据 store_id 值和
  • 分组
  • item_type_id 值发生冲突时,具有非零 partner_id 值的行应该覆盖具有零 partner_id 值的行

使用临时键来构建更深层次的查找结构将提高循环搜索的效率,因为使用 isset() 的键查找总是优于值查找(使用任何技术——即使是提前返回)。

在循环中完成所有分组和过滤后,将与每个商店相关的数据展平为索引数组的关联数组。

代码:(Demo)

$result = [];
foreach ($array as $row) {
    if ($row['partner_id'] || !isset($result[$row['store_id']][$row['item_type_id']])) {
        $result[$row['store_id']][$row['item_type_id']][$row['partner_id']] = $row;
    }
}

var_export(array_map(function($row) { return array_merge(...$row); }, $result));

如果 partner_id 不为零或未遇到 store_id-item_type_id-partner_id 的组合,上述代码段仅在重组数组中添加一行之前。