【问题标题】:Multidimensional array sorting procedure for csv filescsv文件的多维数组排序过程
【发布时间】:2012-07-23 21:23:12
【问题描述】:

在 PHP 中有一个数组。就是这样设置的

$array_var = array(array(1,2,3,4), array(5,6,7,8), array(3,5,3,9));

此数组来自使用 fgetcsv 函数获得的 csv 文件。如果我要正确地回显数组以显示其内容,我会使其显示如下:

field1  field2  field3  field4
  1       2       3       4
  5       6       7       8
  3       5       3       9

等等等等。

现在我想对这个数组进行排序。但我只想对所有数组中的一列进行排序。换句话说,例如,我想在主数组中的每个数组中取第三个值,并按字母顺序升序列出它们。因此,对于特定情况,我们将从上表中取出 field3 中的每个值,并对其进行排序。并且还要做到这一点,以便排序的最终结果将重新排列列,以便它们与它们的值正确对齐。

最终结果

field1  field2  field3  field4
  1       2       3       4
  3       5       3       9
  5       6       7       8

等等等等。

如何做到这一点?

挑战的原因是我试图从 csv 文件的单个列中删除重复项。我认为最快的方法是对值进行排序并在范围内查找匹配项。

【问题讨论】:

  • 我就离开it这里
  • 您输入输出的数据不匹配。 5 没了,你还有 1 吗?
  • 我完全了解array_multisort!请通读我的帖子并仔细了解我的问题。 array_multisort 对多维数组的所有值进行排序。我只希望对数组的每个第 n 个值进行排序,并将所有其他值对齐。阅读倒数第二段并查看底部示例以获取更多信息。
  • 谢谢 Fluffeh 让我解决这个问题。

标签: php arrays algorithm sorting multidimensional-array


【解决方案1】:

很难给你一个准确的答案,因为你在解释中遗漏了一些东西。例如,按其中一列排序但在其他列中有差异的行应该如何在内部排序?它们应该按其他列排序,按原始顺序保留,还是可以按任意顺序放置?

鉴于我解释您问题的方式,我可能会定义自己的类进行比较。

<?php
class ColumnCompare {
  function __construct($column) {
    $this->column = $column;
  }

  function compare($a, $b) {
    if ($a[$this->column] == $b[$this->column]) {
      return 0;
    }
    return ($a[$this->column] < $b[$this->column]) ? -1 : 1;
  }
}

// Hard-coded input
$array_var = array(array(1,2,3,4), array(5,6,7,8), array(3,5,3,9));
$sort_by_col = 2;

// Create object for sorting by a particular column
$obj = new ColumnCompare($sort_by_col);
usort($array_var, array($obj, 'compare'));

// Write CSV to standard output
$sout = fopen('php://stdout', 'w');
foreach ($array_var as $fields) {
  fputcsv($sout, $fields);
}
fclose($sout);
?>

最后你提出了另一个问题,这是不可能回答的。如果您从单个列中删除重复项,那么该行的其余部分会发生什么?应该只保留一行,在这种情况下是哪一行?您也可以通过“删除重复项”来表示您想要删除这些值并将 NULL 放在它们的位置。如果您希望解决该特定问题,则需要提供一些详细信息。

如果您的 CSV 文件非常简单,并且任何重复的行上的所有值都是相同的(在编辑之前的示例中就是这种情况),您可以轻松运行诸如

之类的命令
sort myfile.csv | uniq

但我有一种感觉,它比这更复杂。 uniq 还具有仅返回重复行的设置。也可以编写命令从每一行检索特定列并对其进行操作。但是就像我说的,没有更多信息是不可能构建这样一个命令的。

【讨论】:

  • 这个答案很完美。我针对几个数字序列运行代码,结果是理想的。没有任何例子,我似乎无法理解你的第一个问题。但是无论代码是否有效,它都会像 excel 的排序一样,用它的行来对列进行排序。谢谢!
  • 我还有一个问题。现在 CSV 文件中有标题。如何跳过整个过程的第一行?
  • @SofianeMerah,太好了!关于 CSV 标头,我们现在谈论的是输入文件,对吧?如果你想从命令行中已经存在的文件中删除第一行,只需运行sed 1d inputfile.csv &gt; outputfile.csv。如果您已将文件的内容读入您描述的数组结构中,则只需在 PHP 中运行 array_shift($array_var); 即可删除数组中的第一个元素(在对其进行排序之前)。但是,还有其他方法可以达到相同的结果。如果您对在何处执行此操作有特定要求,请告诉我。
  • @SofianeMerah,如果您的意图是在排序之前删除标题并将它们添加回输出中,您可能想在读取文件后尝试$headers = array_shift($array_var);,并在写入之前尝试array_unshift($array_var, $headers);到新文件。
猜你喜欢
  • 2019-10-22
  • 1970-01-01
  • 2012-06-10
  • 2021-04-23
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多