如何在 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);
无论如何,您都必须提取值。如果您不想使用 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));