Вопрос:

c # csv сортировка списка с использованием третьих столбцов

c# winforms

39 просмотра

4 ответа

56 Репутация автора

У меня есть программа, которая открывает файл CSV с помощью StreamReader и создает таблицу с 4 столбцами и строками для сколь угодно много строк в файле CSV. Это работает правильно, так как создает вывод:

Код товара, описание товара, текущий счет, заказ

A0001, Игрушечная машинка, 4, Да

A0002, Игрушечный грузовик, 1, Нет

Я сохраняю все данные из файла CSV в глобальном списке, не разбивая каждую строку. Когда я создаю таблицу, я разделяю строки, используя «Split (',')», который работает по мере необходимости. Однако я не уверен, как переупорядочить весь список, используя столбец Current Count от наибольшего к наименьшему. Я пробовал следующее, но это дает ошибку на 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', и невозможно найти метод расширения 'Split', принимающий первый аргумент типа 'char' (вы пропустили директиву using или ссылку на сборку?)

Автор: Matt Wilkinson Источник Размещён: 11.08.2019 04:49

Ответы (4)


1 плюс

56 Репутация автора

То, как вы сохранили список, не поможет вам создать таблицу с возможностью сортировки. Чтобы решить вашу проблему, вместо этого List<string>вы должны создать модель (интерфейс IItem и класс Item), используя эти модели для создания List. Затем перед рендерингом таблицы вы можете отсортировать список по любому столбцу.

List<IItem> items = new List<Item>();
items.Add({itemCode: excelData.itemCode , itemDescription: excelData.itemDescription,itemCount: excelData.itemCount, orderCount:excelData.orderCount});
List<IItem> itemsToCreateTable = items.OrderBy(o=>o.itemCount).ToList();
Автор: banu saladi Размещён: 11.08.2019 05:14

2 плюса

21 Репутация автора

OrderByВызов работает на все символы в строке в Globals.items[i]. Вот почему вы видите текущую ошибку. Чтобы отсортировать всю коллекцию, необходимо сделать заказ по списку в целом, например:

var values = Globals.items.Select(line => line.Split(',')); // Select columns for all rows
var orderedListOfValues = values
    .OrderByDescending(cols => int.TryParse(cols[2].Trim(), out var order) ? order : int.MaxValue); // Sort  by count as an integer

Обратите внимание, что в приведенном выше примере сортировки нечисловых значений (например, заголовок) будет использовать максимальное значение целого числа. В зависимости от ожидаемого результата, эти результаты затем могут быть объединены в список строк для представления:

var orderedItems = string.Join(",", orderedListOfValues)

Ура!

Автор: Patrick Размещён: 11.08.2019 05:20

0 плюса

3736 Репутация автора

Непонятно, почему бы вам просто не сделать «Класс» элементов в файле. С помощью «Класса» вы можете сортировать предметы любым удобным для вас способом и различными способами. Кроме того, кажется, что столбец, по которому вы хотите отсортировать (Текущий счетчик), это НОМЕР. Если вы сортируете числа как strings, вы получите все 1 вместе, 2 вместе и т. Д. Пример это будет выглядеть примерно так.

1

10

100

2

20

3

4…

Вы не получите правильный NUMERICAL порядок сортировки, используя строки. Поэтому вы должны отсортировать столбец по номеру, а не по строке, чтобы получить правильный числовой порядок. Идея использования класса в том, что он дает вам полный контроль над сортировкой. Если вы сделаете Listиз, Itemа Itemкласс реализует IComparableинтерфейс, сортировка может быть выполнена с помощью одной строки кода…Items.Sort().

Ниже приведен пример того, что описано выше. Сначала «Класс» Itemдля хранения объектов в файле. Он содержит только свойства, необходимые для этого примера, а именно CompareToметод, который будет использоваться при вызовеItems.Sort().

public class Item : IComparable {

  public string Code { get; set; }
  public string Description { get; set; }
  public int Count { get; set; }
  public bool OnOrder { get; set; }

  public Item(string code, string description, int count, bool onOrder) {
    Code = code;
    Description = description;
    Count = count;
    OnOrder = onOrder;
  }

  public int CompareTo(object obj) {
    Item that = (Item)obj;
    return Count.CompareTo(that.Count);
  } 
}

Ниже приведен пример использования Itemкласса для сортировки списка по столбцу «Текущее количество». A DataGridViewиспользуется для отображения отсортированного списка.

List<Item> Items;

public Form1() {
  InitializeComponent();
}

private void Form1_Load(object sender, EventArgs e) {
  Items = GetData();
  Items.Sort();
  dataGridView1.DataSource = Items;
}

private List<Item> GetData() {
  List<Item> items = new List<Item>();
  Item newItem;
  string line;
  using (StreamReader sr = new StreamReader(@"D:\Test\Test22.csv")) {
    while ((line = sr.ReadLine()) != null) {
      if ((newItem = GetItemFromString(line)) != null) {
        items.Add(newItem);
      }
    }
  }
  return items;
}

private Item GetItemFromString(string itemString) {
  string[] splitArray = itemString.Split(',');
  bool onOrder;
  int count = 0;
  if (splitArray.Length >= 4) {
    int.TryParse(splitArray[2].Trim(), out count);
    if (splitArray[3].Trim() == "Yes")
      onOrder = true;
    else
      onOrder = false;
    return new Item(splitArray[0].Trim(), splitArray[1].Trim(), count, onOrder);
  }
  return null;
}

Надеюсь это поможет.

Автор: JohnG Размещён: 11.08.2019 07:13

0 плюса

14149 Репутация автора

Не прямой ответ на ваш вопрос. Но я думаю, что вы пишете код, который уже доступен бесплатно.

Я настоятельно рекомендую вам использовать пакет 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;}
}

Получение всех MyItems из файла CSV:

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);
    }
}

Прочтите ссылку, чтобы узнать, что делать, если у вас есть специальный разделитель, строка заголовка или что-то еще. Это очень настраиваемый.

Автор: Harald Coppoolse Размещён: 11.08.2019 03:51
Вопросы из категории :
32x32