如何在 C# 中按列升序或降序排序 CSV 文件的所有行.不使用函数拆分

本文关键字:文件 拆分 函数 CSV 排序 降序 升序 | 更新日期: 2023-09-27 18:34:47

我的文件按数字 ID、姓名和薪水列。 我需要按薪水排序。

        2,Sam,500.00
        6,Mike,400.00
        8,Robert,156.00
        3,Steve,100.85
        9,Anderson,234.90

我的代码像这样从 CSV 文件中读取数据...

        List<string[]> fileContent = new List<string[]>();
        using (FileStream reader = File.OpenRead(@"C:'File.csv"))
        using (TextFieldParser parser = new TextFieldParser(reader))
        {
            parser.TrimWhiteSpace = true;
            parser.Delimiters = new[] { "," };
            parser.HasFieldsEnclosedInQuotes = true;
            while (!parser.EndOfData)
            {
                string[] line = parser.ReadFields();
                foreach (string fieldRowCell in line)
                {
                    Console.WriteLine(fieldRowCell);
                    fileContent.Add(line);
                }
            }
        }

最后我需要写一个带有数据的文件 订购

     File.WriteAllLines(@"C:'Result.csv", fieldRowCell);

如何在 C# 中按列升序或降序排序 CSV 文件的所有行.不使用函数拆分

无论如何,您都必须提取值。如果您不想使用 Split,它不是很有用,因为在这种情况下,在不需要的时候会消耗内存,您可以通过行和逗号的数量来获取所需的值。为此,我在我的示例中使用扩展方法 IndexOfNth,然后只找到索引和长度,它允许使用子字符串从行中提取值。

在示例中,数据按列名称排序,列的索引为 1

using System;
using System.Collections.Generic;
public static class StringExtenssion 
{
    public static int IndexOfNth(this string input, string value, int startIndex, int nth)
    {
        if (nth < 1)
            throw new NotSupportedException("Param 'nth' must be greater than 0!");
        if (nth == 1)
            return input.IndexOf(value, startIndex);
        var idx = input.IndexOf(value, startIndex);
        if (idx == -1)
            return -1;
        return input.IndexOfNth(value, idx + 1, --nth);
    }
}
public class Program
{
    public static string GetColumnDataValue(string row, int column)
    {
        int startIndex = 0;
        int length = row.Length;
        if (column != 0)
            startIndex = row.IndexOfNth(",", 0, column) + 1;
        var indexOfNextComma = row.IndexOf(",", startIndex);
        if (indexOfNextComma == -1)
            length = row.Length - startIndex - 1;
        else
            length = indexOfNextComma - startIndex;
        return row.Substring(startIndex, length);
    }
    public static void Main()
    {       
        List<string> list = new List<string> {
            "2,Sam,500.00",
            "6,Mike,400.00",
            "8,Robert,156.00",
            "3,Steve,100.85",
            "9,Anderson,234.90",
        };
        var sortBy = 1;
        list.Sort((a,b) => GetColumnDataValue(a, sortBy).CompareTo(GetColumnDataValue(b, sortBy)));
        foreach(var row in list)
        {
            Console.WriteLine(row);
        }
    }
}

小提琴 https://dotnetfiddle.net/2xohN8

要执行排序,您必须获取列值。如果不用逗号拆分行数据,则无法获取列值。

主要解决方案:

public class Row
{
    public int Id {get;set;}
    public string Name {get;set;}
    public double Value {get;set;}
    public Row(string rowStr)
    {
        string[] cols = rowStr.Split(',');
        Id = int.Parse(cols[0]);
        Name = cols[1];
        Value = double.Parse(cols[2]);
    }
    public string AsString()
    {
        return string.Format("{0},{1},{2}", Id, Name, Value);
    }
}

List<Row> rows = new List<Row>();
using (FileStream reader = File.OpenRead(@"C:'File.csv"))
{
    string rowStr = reader.ReadLine(); 
    rows.Add(new Row(rowStr));  
}
rows = rows.OrderBy(r=>r.Id);
rows = rows.OrderByDescending(r=>r.Name);
foreach(Row row in rows)
{
   outputFile.WriteLine(row.AsString);
}

另一种方式:

public class RowComparer : IComparer<string>
{
    private int _columnIndex;
    public RowComparer(int columnIndex)
    {
        _columnIndex = columnIndex;
    }
    public int Compare(string a, string b)
    {
        string valA = a.Split(',')[columnIndex];
        string valB = b.Split(',')[columnIndex];
        if(valA == valB) return 0;
        return valA >  valB ? 1 : -1;
    }
}
List<string> rows = GetAllLinesFromFile();
// sort ascending by column index 2 (Value)
rows = rows.OrderBy(r=> r, new RowComparer(2));
// sort descending by column index 1 (Name)
rows = rows.OrderByDescending(r=> r, new RowComparer(1));