我在这里做过一些名字处理程序,但是遇到了一些小问题。
我有一个带有名称和状态的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文件中,即可将其输出。
非常感谢!
答案 0 :(得分:0)
假设您需要唯一的用户名,下面是解决方法。
创建一个新的空白用户数组。
遍历users数组。
将用户追加到新用户数组。
密钥应为用户名。
因此,同一位用户每次来访时,他都会覆盖前一个用户,并删除重复的用户。
代码:
$users = [
['John Down', 'Best Ones'],
['John Down', 'Cool Ones']
];
$newUsers = [];
if (! empty($users)) {
foreach ($users as $user) {
$newUsers[$user[0]] = $user[1];
}
}
echo '<pre>';print_r($newUsers);echo '</pre>';
// Output:
Array
(
[John Down] => Cool Ones
)
答案 1 :(得分:0)
我解决了案件: 我从合并数组中删除了第二个键,然后对其进行反序列化,并且仅映射了唯一的键!现在一切正常!
$input = array_map("unserialize", array_unique(array_map("serialize", $merged)));
有时候,我真的很喜欢为您寻求帮助,因为这让我思考!要比平常更深入地思考。
答案 2 :(得分:0)
几件事,
我们需要做的是合并两个数组,但是控制哪个覆盖另一个。我不确定您现在是否(以一种可靠的方式)做到了,但是做到这一点的一种方法是构建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
)
)
如您所见,我们可以控制将数组发送到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
)
)
基本上应该给您提供我们所需要的东西,那么使用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(数组 $ input ,混合 $ column_key [,混合 $ index_key = NULL]):数组
array_column()返回输入的单个列中的值,该值由column_key标识。可选地,可以提供index_key以通过输入数组的index_key列中的值索引返回的数组中的值。
输入:要从中提取一列值的多维数组或对象数组。如果提供了对象数组,则可以直接提取公共属性。为了提取受保护的属性或私有属性,该类必须同时实现__get()和__isset()魔术方法。
column_key 要返回的值列。此值可以是您要检索的列的整数键,也可以是关联数组或属性名称的字符串键名。返回完整的数组或对象也可能为NULL(这与index_key一起用于重新索引数组很有用)。
index_key 用作返回数组的索引/键的列。此值可以是列的整数键,也可以是字符串键名。该值将照常转换为数组键(但是,也允许支持转换为字符串的对象)。