从数组中减去对象以获得差异

时间:2016-04-15 10:13:37

标签: php arrays

我遇到了以下问题:我有一个对象包含有关对象的几个信息,该对象来自PDO-fetchAll()。

$sSql = "SELECT * FROM my_table";
$result = $this->db->fetchAll($sSql);

输出如下:

array(7) {
    [0]=>
        object(stdClass)#8 (13) {
            ["id"]=> string(6) "393605"
            ["profile_id"]=> string(2) "38"
            ["sku"]=> string(11) "01-SSC-4314"
    [1]=>
        object(stdClass)#7 (13) {
            ["id"]=> string(6) "393606"
            ["profile_id"]=> string(2) "38"
            ["sku"]=> string(11) "01-SSC-4315"  
}

到目前为止一切都很好。现在我得到另一个输入数组。数组看起来像这样。

array(7) {
    [0]=>
        array(19) {
            [0]=> string(11) "01-SSC-4314"
            [1]=> string(10) "3406190219"
            [2]=> string(29) "24X7 SUPPORT FOR NSA 2600 1YR"
    }
    [1]=>
        array(19) {
            [0]=> string(11) "01-SSC-4316"
            [1]=> string(10) "3406190219"
            [2]=> string(29) "24X7 SUPPORT FOR NSA 2601 1YR"
    }
    [2]=>
        array(19) {
            [0]=> string(11) "01-SSC-4317"
            [1]=> string(10) "3406190219"
            [2]=> string(29) "24X7 SUPPORT FOR NSA 2600 3YR"
    }
}

我想要什么:我想要这两个给定元素之间的区别。我正在考虑使用array_diff,但每当我试图将我的对象转换为数组时,它最终仍然是一个对象。

(供参考:我试过$ aArray =(数组)$ result;(之后仍然是一个对象)PHP 5.3

举个例子,我需要的是什么:

在我的对象中,有两个不同的条目。让我们关注这个案例的sku。有一个* 4314和一个* 4315。

在我的输入数组中,有3个元素。如您所见,缺少* 4315条目。这正是我现在所需要的。

因此,我需要从一组已存在的数据中减去给定输入数组的集合。

  

输入 - 对象=差异

我也可以遍历对象并检查if a value exists in an array,但我认为这不适合更大的对象/数组。 另外,根据我的尝试:

$aMissing = array();
    // now lets see what what items we have now
    foreach($result as $res)
    {
        if(!in_array($res->sku, $lines)) {
            $aMissing = "";
        } 

    }

我没有参考资料,要添加到$aMissing的内容。

输出应该是这样的:

  

缺少物品:01-SSC-4315,(...)

建议?想法?

1 个答案:

答案 0 :(得分:1)

要求:找不到主人'来自项目来源列表的SKU条目。

working example at: eval.in

鉴于:

  • SKU条目的来源列表($sourceSkuList)。每个条目都是stdClass对象。
  • SKU条目的主列表($masterSkuList),其中每个条目都是一个数组。我假设第一个条目是SKU。

输出:

  • 不在MasterSkuList
  • 中的来源条目SKU

方法:

SKU并未列出这些列表,据我所知,这些列表未按SKU排序。

在最糟糕的情况下,最有效的方法是在每个列表中包含一个顺序传递。这将要求每个列表按SKU顺序排序。

我们能接近这个吗?是...

  • 使用$masterSkuList构建一个数组,该数组在SKU上键入。这将是非常快速的检查,因为它是一个键查找。这可以在一个顺序传递中创建。

  • 使用SKU作为键,依次检查另一个数组(sourceSkuList)。如果未找到,请将其添加到缺失列表中。

代码:

注意:我使用额外的变量,因此更容易理解。

// create a master sku list keyed by SKU for fast checking later...
$skuLookupList = array();

// fill it... assume key Zero is always the SKU entry
foreach ($masterSkuList as $position => $sku) {
    $skuLookupList[$sku[0]] = $position; 
}

// output in here...
$missingSkuList = array();

// check each entry...
foreach ($sourceSkuList as $entry) {

    $curSku = $entry->sku;

    // check source sku exists in the lookup...
    if (!isset($skuLookupList[$curSku])) { // add it to the missing list
        $missingSkuList[$curSku] = (array) $entry;
    }
}

输出:缺少SKU列表:

Array
(
    [01-SSC-4315] => Array
        (
            [id] => 393606
            [profile_id] => 38
            [sku] => 01-SSC-4315
        )
)

测试数据:

--- Source (objects) - $sourceSkuList ------
Array(
    [0] => stdClass Object
        (
            [id] => 393605
            [profile_id] => 38
            [sku] => 01-SSC-4314
        )
    [1] => stdClass Object
        (
            [id] => 393606
            [profile_id] => 38
            [sku] => 01-SSC-4315
        )
)
--- Master (array) - $masterSkuList ------
Array(
    [0] => Array
        (
            [0] => 01-SSC-4314
            [1] => 3406190219
            [2] => 24X7 SUPPORT FOR NSA 2600 1YR
        )
    [1] => Array
        (
            [0] => 01-SSC-4316
            [1] => 3406190219
            [2] => 24X7 SUPPORT FOR NSA 2601 1YR
        )
    [2] => Array
        (
            [0] => 01-SSC-4317
            [1] => 3406190219
            [2] => 24X7 SUPPORT FOR NSA 2600 3YR
        )
)