c# csv使用第三列对列表进行排序

我有一个程序,可以使用 StreamReader 打开 CSV 文件,并根据 CSV 文件中的行数创建一个包含 4 列和行的表。这可以正常工作,就像创建以下输出一样:

商品代码、商品描述、当前数量、订购时

A0001,玩具车,4,有

A0002,玩具卡车,1,无

我将 CSV 文件中的所有数据保存在全局列表中,而不拆分每一行。当我创建表时,我使用“Split(',')”分割行,这在当时需要时工作。但是我不确定如何使用“当前计数”列从最大到最小重新排序整个列表。我已尝试以下操作,但在 Split(',') 上出现错误。

public static class Globals

{

    public static List<string> items = new List<string>();

}

private void createTableWithOrder(int order)

{

    for (int i = 0; i < Globals.items.; i++)

    {

         var values = Globals.items[i].Split(',');


         if (order == 1)

         {

              values = Globals.items[i].OrderBy(itemDesc => itemDesc.Split(',')).ToList();

         }

    }

}

给出的错误如下:


“char”不包含“Split”的定义,并且找不到接受“char”类型的第一个参数的扩展方法“Split”(您是否缺少 using 指令或程序集引用?)


慕工程0101907
浏览 199回答 4
4回答

摇曳的蔷薇

该OrderBy调用正在处理处字符串中的所有字符Globals.items[i]。这就是您看到当前错误的原因。为了对整个集合进行排序,需要对整个列表进行排序,例如:var values = Globals.items.Select(line => line.Split(',')); // Select columns for all rowsvar orderedListOfValues = values&nbsp; &nbsp; .OrderByDescending(cols => int.TryParse(cols[2].Trim(), out var order) ? order : int.MaxValue); // Sort&nbsp; by count as an integer请注意,在上面的示例中,对非数字值(例如标题)进行排序将使用整数的最大值。根据预期的结果,这些结果可以合并回字符串列表中以供演示:var orderedItems = string.Join(",", orderedListOfValues)干杯!

江户川乱折腾

您存储列表的方式不会帮助您生成具有排序功能的表。要解决您的问题,List<string>您应该使用这些模型创建列表来创建模型(IItem 接口和 Item 类)。然后在渲染表格之前,您可以根据您喜欢的任何列对列表进行排序。List<IItem>&nbsp;items&nbsp;=&nbsp;new&nbsp;List<Item>(); items.Add({itemCode:&nbsp;excelData.itemCode&nbsp;,&nbsp;itemDescription:&nbsp;excelData.itemDescription,itemCount:&nbsp;excelData.itemCount,&nbsp;orderCount:excelData.orderCount}); List<IItem>&nbsp;itemsToCreateTable&nbsp;=&nbsp;items.OrderBy(o=>o.itemCount).ToList();

哆啦的时光机

不是直接回答你的问题。但我认为您正在编写已经可以免费使用的代码。我强烈建议您使用nuget 包 CSV Helper。它接受任何文本流、字符串、文本阅读器等,并将 CSV 文件转换为您期望类型的 IEnumerable。它可以在有或没有包含列的标题行的情况下使用class MyItem{    public string Code {get; set;}    public string Description {get; set;}    public int Count {get; set;}    public bool OnOrder {get; set;}}从 CSV 文件中获取所有 MyItems:string myCsvFileName = ...using (TextReader reader = new StreamReader(myCsvFileName)){    using (var csv = new CsvReader(reader))    {            IEnumerable<MyItem> items = reader.GetRecords<MyItem>();        // you can do any Linq with this:        var allItems = items.ToList();        // or if you only need some records:        var unAvailableItems = items.Where(item => item.Count == 0);    }}阅读链接以了解如果您有特殊分隔符、标题行或其他任何内容该怎么办。它是高度可配置的。

jeck猫

目前尚不清楚为什么您不简单地为文件中的项目创建一个“类”。通过“类别”,您可以以任何您选择的方式和多种方式对项目进行排序。此外,您想要排序的列(当前计数)似乎是数字。如果您将数字排序为strings,您将得到所有 1 在一起、2 在一起等。例如,它看起来像这样。11010022034 …您将无法使用字符串获得正确的数字排序顺序。因此,您必须按数字而不是字符串对列进行排序才能获得正确的数字顺序。使用类背后的想法是它可以让您完全控制排序。如果你创建一个List并且Item该类Item实现了该IComparable接口,则可以用一行代码完成排序......Items.Sort().下面是上述内容的示例。首先是“类”Item来保存文件中的对象。它仅包含此示例所需的属性,即CompareTo调用时将使用的方法Items.Sort().public class Item : IComparable {&nbsp; public string Code { get; set; }&nbsp; public string Description { get; set; }&nbsp; public int Count { get; set; }&nbsp; public bool OnOrder { get; set; }&nbsp; public Item(string code, string description, int count, bool onOrder) {&nbsp; &nbsp; Code = code;&nbsp; &nbsp; Description = description;&nbsp; &nbsp; Count = count;&nbsp; &nbsp; OnOrder = onOrder;&nbsp; }&nbsp; public int CompareTo(object obj) {&nbsp; &nbsp; Item that = (Item)obj;&nbsp; &nbsp; return Count.CompareTo(that.Count);&nbsp; }&nbsp;}Item下面是使用该类按“当前计数”列对列表进行排序的示例。ADataGridView用于显示排序列表。List<Item> Items;public Form1() {&nbsp; InitializeComponent();}private void Form1_Load(object sender, EventArgs e) {&nbsp; Items = GetData();&nbsp; Items.Sort();&nbsp; dataGridView1.DataSource = Items;}private List<Item> GetData() {&nbsp; List<Item> items = new List<Item>();&nbsp; Item newItem;&nbsp; string line;&nbsp; using (StreamReader sr = new StreamReader(@"D:\Test\Test22.csv")) {&nbsp; &nbsp; while ((line = sr.ReadLine()) != null) {&nbsp; &nbsp; &nbsp; if ((newItem = GetItemFromString(line)) != null) {&nbsp; &nbsp; &nbsp; &nbsp; items.Add(newItem);&nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }&nbsp; }&nbsp; return items;}private Item GetItemFromString(string itemString) {&nbsp; string[] splitArray = itemString.Split(',');&nbsp; bool onOrder;&nbsp; int count = 0;&nbsp; if (splitArray.Length >= 4) {&nbsp; &nbsp; int.TryParse(splitArray[2].Trim(), out count);&nbsp; &nbsp; if (splitArray[3].Trim() == "Yes")&nbsp; &nbsp; &nbsp; onOrder = true;&nbsp; &nbsp; else&nbsp; &nbsp; &nbsp; onOrder = false;&nbsp; &nbsp; return new Item(splitArray[0].Trim(), splitArray[1].Trim(), count, onOrder);&nbsp; }&nbsp; return null;}希望这可以帮助。
打开App,查看更多内容
随时随地看视频慕课网APP