【问题标题】:Sort by associative column in an array csv按数组 csv 中的关联列排序
【发布时间】:2018-07-14 17:41:01
【问题描述】:

我正在尝试按第 8 列对数组进行排序。第 8 列存储位置 1、位置 2、位置 3 等数据。 col8 必须仅与 col7 相关联,因为 col7 包含应由 col8 排序的答案。例如,如果 col8 = 位置 1 和 col7= 黄色,col8 = 位置 2 和 col7= 黑色,它应该打印黄色黑色。 我尝试实现我在此处找到的所有示例,但它不起作用。

    function readCsv($fileName){

    $handle = fopen($fileName, "r");

    $data=array();

    while ($col = fgetcsv($handle, 1000, ",")) { 

        $data[] = [

            'Section' => $col[0],   
            'Q #' => $col [1],
            'Q Type' => $col[2],
            'Q Title' => $col[3],
            'Q Text' => $col[4],
            'Bonus' => $col [5],
            'Difficulty' => $col[6],
            'Answer' => $col[7],
            'Answer Match' => $col[8],
            'Responses'=> $col[9], 

        ]; 

    }

   usort($data, function($a, $b) { return strcmp($a["Answer Match"], $b["Answer Match"]); });


    fclose($handle);
    return $data;
}

应该返回黄色黑色紫色。

我尝试使用此代码:

usort($data, function($a, $b) { return strcmp($a["Answer Match"], $b["Answer Match"]); });

但是,它是对第 1 列进行排序,而不是对第 7 列进行排序。

我的输出不正确,因为它打印了标题 (# Partipant) 并将参与者按字母顺序排列:

1> 参与者 2 橙色 白色 黑色 2>#参与者黑黄紫

正确的输出是:

1> 参与者 1 黄色 黑色 紫色

2> 参与者 2 橙色 黑色 白色

【问题讨论】:

  • 什么应该打印黄黑?有点不清楚……
  • 提供 csv 示例和结果示例(如果你有一个或者你可以做一个)
  • @MrSmile 它应该首先打印黄色,因为第 8 列的位置为 1。我想按位置排序,而不是按第 7 列的字母顺序。
  • @MrSmile 我将表格包含在上面的问题中。
  • 你有多少行?您可能想先遍历所有行以确定每一行的位置,对吧?

标签: php arrays csv sorting


【解决方案1】:

当您已经拥有所有数据集时,您必须在 while 之后使用 usort。而且你的比较功能不好,看这里:

function readCsv($fileName){
$handle = fopen($fileName, "r");
$data=array();
while ($col = fgetcsv($handle, 1000, ",")) {
    $data[] = [
        'Section' => $col[0],
        'Q #' => $col[1],
        'Q Type' => $col[2],
        'Q Title' => $col[3],
        'Q Text' => $col[4],
        'Bonus' => $col [5],
        'Difficulty' => $col[6],
        'Answer' => $col[7],
        'Answer Match' => $col[8],
        'Responses'=> $col[9],

    ];
}
usort($data, function($a, $b) { return strcmp($a["Answer Match"], $b["Answer Match"]); });
fclose($handle);
return $data;
}

结果:

【讨论】:

  • 我的数组有 9 列和 95 行。出于某种原因,您的解决方案对第一列进行排序,而不是对第 7 列和第 8 列进行排序。:(
  • @find83,这很奇怪,因为我已经测试过脚本。看看我编辑过的帖子,也许你漏掉了什么。
  • 我试过你的代码,但它只对第 1 列进行排序。我在上面的问题中包含了更多信息。
  • @find83 请更新您的完整功能代码。您确定在 之后运行 usort 吗?
  • 我刚刚更新了我的代码。它仍在对第 1 列进行排序 :(
【解决方案2】:

听起来您只想对第 7 列和第 8 列进行排序;并且您想将第 1...6,9 列“未排序”/保留原样。这在数组的上下文中有点奇怪,因此需要一些解决方法:

//Your code for context
function readCsv($fileName){
$handle = fopen($fileName, "r");
$data=array();
while ($col = fgetcsv($handle, 1000, ",")) { 
    $data[] = //removed
}

//take columns 7 and 8 out, and sort them separately.
$sortedAnswer = array_column($data,'Answer','Answer Match');
ksort($sortedAnswer);
reset($sortedAnswer);

//pluck the columns back in.
$data = array_map(function($v) use (&$sortedAnswer) {
  $v['Answer'] = current($sortedAnswer);
  $v['Answer Match'] = key($sortedAnswer);
  next($sortedAnswer);
  return $v;
}, $data);
unset($sortedAnswer);

//your code for context
fclose($handle);
return $data;
}

有可能,我完全误解了你的问题。在那种情况下,我道歉。

预计到达时间: array_map 部分过于复杂,没有任何理由;一旦我知道答案是正确的方向,我会将其更改为 foreach。

【讨论】:

  • 不幸的是,使用您的代码,它只打印第 1 列。它不打印第 7 列和第 8 列 :(
  • 您在打印$data吗? $sortedAnswer 只是一个临时变量,无用的后记。
  • 我正在打印 $data。在这种情况下如何使用$sortedAnswer
  • 你不应该使用 $sortedAnswer。这只是我的猜测,因为我不明白 $data 怎么可以只有一列;我仍然没有。
  • 我添加了一些代码以确保我们讨论的是相同的数组。
猜你喜欢
  • 2012-01-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-02-21
  • 1970-01-01
  • 1970-01-01
  • 2011-07-09
相关资源
最近更新 更多