我在这里做过一些名称处理程序,但是遇到了小巧的菜鸟问题。
我有一个包含名称和状态的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
)
Dunno接下来是什么-我要的是,如果我查询的名称与第一个CSV文件中的名称相同,然后隐藏该名称并显示我的名称。
我试图与
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
的顺序覆盖哪个数组。第二个数组(或右边的数组)将覆盖左边的数组。因此,它从左到右读取。那么,现在从数据库中获取该结构的最简单方法是什么?在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,您可以在读取文件(通过添加密钥)并使用
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,混合$ column_key [,混合$ index_key = NULL]):数组
array_column()从输入的单个列中返回由column_key标识的值。可选地,可以提供index_key以通过输入数组的index_key列中的值索引返回的数组中的值。
输入多维数组或对象数组,可从中提取一列值。如果提供了对象数组,则可以直接提取公共属性。为了提取受保护的或私有的属性,该类必须同时实现__get()和__isset()魔术方法。
column_key要返回的值的列。此值可以是您要检索的列的整数键,也可以是关联数组或属性名称的字符串键名。返回完整的数组或对象也可能为NULL(这与index_key一起用于重新索引数组很有用)。
index_key用作返回数组的索引/键的列。此值可以是列的整数键,也可以是字符串键名。该值将照常转换为数组键(但是,也允许支持转换为字符串的对象)。
关于php - 从合并数组中删除重复项,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/55035776/