php - 从合并数组中删除重复项

标签 php mysql arrays

我一直在这里做一些名称处理器,我遇到了一些小问题,有点菜鸟式的问题。

我有包含名称和状态的 CSV 文件,仅按“Cool Ones”状态过滤它们,然后我查询 SQL,并获取我手动输入的另一个名称列表。 这是代码示例,我使用 CSV 文件、过滤器、查询 SQL,然后创建数组、合并数组并按字母顺序排序。

   $nameFile = "names/$eid.csv";
            $content = array_map('str_getcsv', file($nameFile));
            $filteredData = array_filter($content, function($v){
            return $v['1'] === 'Cool Ones'; },ARRAY_FILTER_USE_BOTH); //because in this file there are also 'Not Cool Ones'

            $freePeople = array(); 
            $sth = $DBcon->prepare("SELECT guestName, guestType FROM guestList WHERE forEvent = '$eid' ORDER BY 'guestName'");
            $sth->execute();
            $result2 = $sth->fetchAll(PDO::FETCH_NUM);

            $listNames = array();
            foreach($result2 as $row) {
               $listNames[] = $row['0'];
               $freeGuestName = $row['0'];
               $freeGuestType = $row['1'];
            }

            $merged = array_merge($filteredData, $result2);
            $sortedGuests = usort($merged, "sortGuestNames");

所以我的问题在于,当输出数组时,我得到重复的结果,

[50] => Array
    (
        [0] => John Down
        [1] => Best Ones
    )

[51] => Array
    (
        [0] => John Down
        [1] => Cool Ones
    )

不知道接下来会发生什么 - 我希望如果我查询的名称与第一个 CSV 文件中的名称相同,则隐藏此名称并显示我的名称。

我试图用以下方法取消设置 key

foreach($merged[$i]['0'] as $key => $value) {
if (in_array($merged[$i]['0'], $value)) {
    unset($merged[$i]['0'][$key]);
}

}

但运气不好,仍然输出重复项。

您可以提出更好的方法。 我想 - 也许打开 CSV,查询 SQL 并找到我的手动名称 - 在打开的 CSV 字段中查找,在其中附加我的状态,合并并将它们推送到 SQL 数据库或新的 CSV 文件,以便在其中输出。

非常感谢!

最佳答案

一些事情,

我们需要做的事情是合并两个数组,但控制哪个数组覆盖另一个数组。我不确定你现在是否可以(以可靠的方式)做到这一点,但一种方法是构建 2 个数组。两者具有相同的结构,并且键是您的独特字段,因此我们想要这样:

$csv = ['John Down' =>  ['John Down','Best Ones']];   
$db = ['John Down' => ['John Down','Cool Ones']];

然后当我们进行数组合并时,第二个参数将覆盖第一个参数。所以如果我们这样做

$csv = ['John Down' =>  ['John Down','Best Ones']];
$db = ['John Down' => ['John Down','Cool Ones']];

print_r(array_merge($csv, $db));
echo "\n";
print_r(array_merge($db, $csv));

输出:

// print_r(array_merge($csv, $db));
Array
(
    [John Down] => Array
        (
            [0] => John Down
            [1] => Cool Ones
        )

)

//print_r(array_merge($db, $csv))
Array
(
    [John Down] => Array
        (
            [0] => John Down
            [1] => Best Ones
        )

)

Sandbox

正如你所看到的,我们可以按照发送到array_merge的顺序来控制哪个数组被覆盖。 in。第二个(或右边的)覆盖左边的。所以简单地从左到右阅读。

那么现在从数据库获取该结构的最简单方法是什么?在PDO中我们可以使用FETCH_GROUP它采用查询中的第一列并将其用作顶级键。

$sth = $DBcon->prepare("SELECT guestName, guestType FROM guestList WHERE forEvent = :eid GROUP BY guestName ORDER BY guestName");
//-- add `GROUP BY guestName` we don't want duplicates anyway
//-- no quotes see: ... ORDER BY 'guestName');
//-- use prepared statements
$sth->execute(['eid'=>$eid]);            
$result2 = $sth->fetchAll(PDO::FETCH_NUM);

$result2 = array_column($result2, null, 0);

对于 CSV,您可以在读取文件(通过添加 key )并使用 fgetcsv 时以这种方式构建它。或者你可以使用这个技巧(上面也使用过):

$csv = [['John Down','Best Ones']];

print_r(array_column($csv, null, 0));

输出

Array
(
    [John Down] => Array
        (
            [0] => John Down
            [1] => Best Ones
        )

)

Sandbox

这基本上可以满足我们的需要,然后使用 array_merge 就很简单了.

值得一提的是,如果您的数据库或 CSV 不是唯一的,您也会在那里得到一些重复的删除,您可能需要考虑到这一点。

删除重复项很好,但您需要确保以可重复且可靠的方式删除正确的重复项。使用array_merge无论行从数据库和文件中进入的顺序如何,我们都可以控制。

夏天

因此,如果我们将所有这些放在一起,这就是您所需要的:

$nameFile = "names/$eid.csv";
$content = array_map('str_getcsv', file($nameFile));
$filteredData = array_filter($content, function($v){
    return $v['1'] === 'Cool Ones';
},ARRAY_FILTER_USE_BOTH); //because in this file there are also 'Not Cool Ones'

$sth = $DBcon->prepare("SELECT guestName, guestType FROM guestList WHERE forEvent = :eid GROUP BY guestName ORDER BY guestName");
$sth->execute(['eid'=>$eid]);            
$result2 = $sth->fetchAll(PDO::FETCH_NUM);

$listNames = array_column($result2, 0);

$merged = array_merge(array_column($filteredData, null, 0), array_column($result2, null, 0));
$sortedGuests = usort($merged, "sortGuestNames");

因此,我们没有在修补问题时添加代码,而是找到根本原因并修复它,并减少了几行代码。只要您的 CSV 格式正确,此操作就会起作用。 guestName, guestType

干杯!

http://php.net/manual/en/function.array-column.php

array_column ( array $input , mixed $column_key [, mixed $index_key = NULL ] ) : array

array_column() returns the values from a single column of the input, identified by the column_key. Optionally, an index_key may be provided to index the values in the returned array by the values from the index_key column of the input array.

input A multi-dimensional array or an array of objects from which to pull a column of values from. If an array of objects is provided, then public properties can be directly pulled. In order for protected or private properties to be pulled, the class must implement both the __get() and __isset() magic methods.

column_key The column of values to return. This value may be an integer key of the column you wish to retrieve, or it may be a string key name for an associative array or property name. It may also be NULL to return complete arrays or objects (this is useful together with index_key to reindex the array).

index_key The column to use as the index/keys for the returned array. This value may be the integer key of the column, or it may be the string key name. The value is cast as usual for array keys (however, objects supporting conversion to string are also allowed).

关于php - 从合并数组中删除重复项,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55035776/

相关文章:

php - 按名称搜索带有日期的结果

mysql - 查询最近X天内哪些组数据具有相同的值

python - 从数组值过滤字典

python - for循环没有执行两次

mysql - 比较2个表的数据

c - 查找数组中两个数字的目标和

php - mysql数据库auto_id在数据库中排列错误

php - 注册页面未将数据保存到Mysql数据库

php - 非顺序分页 PHP

php - Laravel 项目 ERR_EMPTY_RESPONSE