【问题标题】:How Can I Merge All Duplicates In Array Based On One Key's Value?如何根据一个键的值合并数组中的所有重复项?
【发布时间】:2015-12-13 14:42:03
【问题描述】:

我尝试了各种解决方案,但似乎没有一个能满足我的需求——或者我不明白如何改变它们来解决我的特定问题。基本上,我从我的 SQL 服务器返回一堆行。查询如下所示:

$params = array(&$search, &$search, &$search, &$search, &$search, &$search, &$search, &$search);

$tsql = "SELECT Item.ID, Item.ItemLookupCode, nitroasl_pamtable.ManufacturerPartNumber, SupplierList.ReorderNumber, Item.Notes,
         Item.Description, Item.ExtendedDescription, Item.Quantity, nitroasl_pamtable.SpoofStock, Item.Price,
         nitroasl_pamtable.PAM_Keywords, Item.PictureName
         FROM Item
         INNER JOIN nitroasl_pamtable ON Item.ID = nitroasl_pamtable.ItemID
         INNER JOIN SupplierList ON Item.ID = SupplierList.ItemID
         WHERE (Item.ItemLookupCode LIKE '%' + ? + '%' AND Price > 0.00 AND WebItem = 1)
         OR (Item.ID LIKE '%' + ? + '%' AND Price > 0.00 AND WebItem = 1)
         OR (nitroasl_pamtable.ManufacturerPartNumber LIKE '%' + ? + '%' AND Price > 0.00 AND WebItem = 1)
         OR (SupplierList.ReorderNumber LIKE '%' + ? + '%' AND Price > 0.00 AND WebItem = 1)
         OR (Item.Notes LIKE '%' + ? + '%' AND Price > 0.00 AND WebItem = 1)
         OR (Item.Description LIKE '%' + ? + '%' AND Price > 0.00 AND WebItem = 1)
         OR (Item.ExtendedDescription LIKE '%' + ? + '%' AND Price > 0.00 AND WebItem = 1)
         OR (nitroasl_pamtable.PAM_Keywords LIKE '%' + ? + '%' AND Price > 0.00 AND WebItem = 1)";

// Allows us to determine the number of rows returned
$cursorType = array('Scrollable' => SQLSRV_CURSOR_KEYSET);

$getProducts = sqlsrv_query($conn, $tsql, $params, $cursorType);

然后我使用以下内容将行放入数组中:

// Put results into an array
while( $row = sqlsrv_fetch_array( $getProducts, SQLSRV_FETCH_ASSOC))
{
  $results['results'][] = $row;
}

$results['results'] 在我搜索“tp-ac1750 时看起来像这样(删除了一些返回的列以便于查看) :

Array (

  [results] => Array (

    [0] => Array (

      [ItemLookupCode] => TP-AC1750

      [ReorderNumber] => ARCHERC7

    )

    [1] => Array (

      [ItemLookupCode] => TP-AC1750

      [ReorderNumber] => N82E16833704177

    )

    [2] => Array (

      [ItemLookupCode] => TP-AC1750

      [ReorderNumber] => 7681617

    )

    [3] => Array (

      [ItemLookupCode] => TP-AC1750

      [ReorderNumber] => ARCHERC7

    )

  )

  [keywords] => tp-ac1750

)

我希望数组看起来像这样:

Array (

  [results] => Array (

    [0] => Array (

      [ItemLookupCode] => TP-AC1750

      [ReorderNumber] => Array (

        [0] => ARCHERC7

        [1] => N82E16833704177

        [2] => 7681617

      )

    )

  )

)

我试过了:

  • array_unique
  • array_unique_recursive
  • array_walk_recursive
  • array_merge_recursive
  • 还有更多(各种组合)

但我似乎无法做到正确。这是我现在正在尝试的:

// Remove duplicates
$results['results'] = merge_duplicates( $results['results'] );

//***********************************************
// Merge duplicate arrays and their values
//***********************************************
function merge_duplicates( $array )
{

  // Build temporary array for array_unique
  $tmp = array();
  foreach( $array as $key => $value ) {
    $tmp[ $key ] = $value;
  }

  // Find duplicates in temporary array
  $tmp = array_unique( $tmp, SORT_REGULAR );

  // Remove duplicates from original array
  foreach( $array as $key => $value ) {

    if ( !array_key_exists( $key, $tmp ) ) {

      unset( $array[ $key ] );

    }

  }

  return $array;

}

有没有办法完成这种类型的合并?有没有办法在 SQL 查询期间合并这些重复项?任何意见,将不胜感激!在此先感谢:)

更新(正在使用的完整数组)

这是我需要使用此合并的实际数组(我仍然想使用 ItemLookupCode 作为唯一键,但合并所有其他同级键):

Array (

  [0] => Array (

    [ID] => 8265
    [ItemLookupCode] => TP-AC1750
    [ManufacturerPartNumber] => Archer C7
    [ReorderNumber] => ARCHERC7
    [Notes] => TP-LINK Archer C7 AC1750 Routr
    [Description] => TP-LINK Archer C7 AC1750 Routr
    [ExtendedDescription] => TP-Link Archer C7 Wireless-AC1750 Dual-Band Gigabit Router
    [Quantity] => 0
    [SpoofStock] =>
    [Price] => 129.9500
    [PAM_Keywords] =>
    [PictureName] => tp-ac1750.jpg

  )

  [1] => Array (

    [ID] => 8265
    [ItemLookupCode] => TP-AC1750
    [ManufacturerPartNumber] => Archer C7
    [ReorderNumber] => N82E16833704177
    [Notes] => TP-LINK Archer C7 AC1750 Routr
    [Description] => TP-LINK Archer C7 AC1750 Routr
    [ExtendedDescription] => TP-Link Archer C7 Wireless-AC1750 Dual-Band Gigabit Router
    [Quantity] => 0
    [SpoofStock] =>
    [Price] => 129.9500
    [PAM_Keywords] =>
    [PictureName] => tp-ac1750.jpg

  )

  [2] => Array (

    [ID] => 8265
    [ItemLookupCode] => TP-AC1750
    [ManufacturerPartNumber] => Archer C7
    [ReorderNumber] => 7681617
    [Notes] => TP-LINK Archer C7 AC1750 Routr
    [Description] => TP-LINK Archer C7 AC1750 Routr
    [ExtendedDescription] => TP-Link Archer C7 Wireless-AC1750 Dual-Band Gigabit Router
    [Quantity] => 0
    [SpoofStock] =>
    [Price] => 129.9500
    [PAM_Keywords] =>
    [PictureName] => tp-ac1750.jpg

  )

  [3] => Array (

    [ID] => 8265
    [ItemLookupCode] => TP-AC1750
    [ManufacturerPartNumber] => Archer C7
    [ReorderNumber] => ARCHERC7
    [Notes] => TP-LINK Archer C7 AC1750 Routr
    [Description] => TP-LINK Archer C7 AC1750 Routr
    [ExtendedDescription] => TP-Link Archer C7 Wireless-AC1750 Dual-Band Gigabit Router
    [Quantity] => 0
    [SpoofStock] =>
    [Price] => 129.9500
    [PAM_Keywords] =>
    [PictureName] => tp-ac1750.jpg

  )

)

【问题讨论】:

  • 这并不是您真正想要的,但它可能有用。 geneticcoder.blogspot.com/2015/05/…
  • 那篇文章中有一些可能性。我将进行实验,看看会发生什么:) 这些方法有一种反复出现的主题,我不知道该怎么做......其中许多函数,如array_merge_recursive,希望将两个数组传递给函数进行比较。 ..我需要比较许多数组(不仅仅是两个)...
  • 您仍然在 INNER JOINing 并(可能)为单个结果集中的每个 Item 返回许多行。这不是我推荐的。
  • 这个问题是在我们开始在另一个线程中讨论之前提出的 :) 所以这是我最初的查询......

标签: php sql arrays tsql php-5.6


【解决方案1】:

我能想到的最快方法:

<?php
$results = array(
    array('ItemLookupCode' => 'name1', 'ReorderNumber' => 1),
    array('ItemLookupCode' => 'name1', 'ReorderNumber' => 2),
    array('ItemLookupCode' => 'name1', 'ReorderNumber' => 3),
    array('ItemLookupCode' => 'name1', 'ReorderNumber' => 2),
    array('ItemLookupCode' => 'name2', 'ReorderNumber' => 1),
    array('ItemLookupCode' => 'name2', 'ReorderNumber' => 1),
);

function group($main, $item)  {
    if(!isset($main[$item['ItemLookupCode']])) {
        $main[$item['ItemLookupCode']] = array('ReorderNumber' => array());
    }
    if(!in_array($item['ReorderNumber'], $main[$item['ItemLookupCode']]['ReorderNumber'])) {
        $main[$item['ItemLookupCode']]['ReorderNumber'][] = $item['ReorderNumber'];
    }
    return $main;
}

$formatted_result = array();
foreach(array_reduce($results, "group") as $name => $item) {
    $formatted_result[] = array(
        'ItemLookupCode' => $name,
        'ReorderNumber' => $item
    );
}
print_r($formatted_result);

【讨论】:

  • 这实际上将组合结果放入名为 ReorderNumber 的数组中,该数组位于名为 ReorderNumber 的父数组中。可笑的是,我无法弄清楚如何将孩子的价值观提升到父母的水平......
  • Array ( [0] =&gt; Array ( [ID] =&gt; 8265 [ReorderNumber] =&gt; Array ( [ReorderNumber] =&gt; Array ( [0] =&gt; N82E16833704177 [1] =&gt; 7681617 [2] =&gt; ARCHERC7 [3] =&gt; ARCHERC7 ) ) ) ) 我将 ItemLookupCode 更改为 ID 顺便说一句。
  • 如何调整这个脚本,使ReorderNumber不存在多个级别?
猜你喜欢
  • 2021-07-16
  • 2017-12-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-11-18
  • 1970-01-01
  • 2017-02-09
  • 2019-06-09
相关资源
最近更新 更多