Как я могу сортировать файлы CSV по столбцам, как мы видим в электронных таблицах?C#

Место общения программистов C#
Ответить Пред. темаСлед. тема
Anonymous
 Как я могу сортировать файлы CSV по столбцам, как мы видим в электронных таблицах?

Сообщение Anonymous »

Предположим, у меня есть следующий CSV-файл:

Код: Выделить всё

Column1,Column2,Column3
C,3,1
B,2,2
A,3,3
C,3,10
B,2,20
A,2,30
C,3,100
B,1,200
A,1,300
Я хочу отсортировать
  • Сначала по столбцу 1
  • Второ по Столбец 2
  • Третий по столбцу 3
Итак, результат должен быть следующим:

Код: Выделить всё

Column1,Column2,Column3
A,1,300
A,2,30
A,3,3
B,1,200
B,2,2
B,2,20
C,3,1
C,3,10
C,3,100
Для сортировки CSV по столбцам в порядке возрастания/убывания я создал следующий класс:

Код: Выделить всё

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;

namespace SikorskiLibMemoryLess
{
public enum SortTypeEnum
{
Ascending,
Descending
}

public static class ListExtensions
{
public static string ToCommaSeparatedString(this List list)
{
if (list == null || !list.Any())
{
return string.Empty;
}

return string.Join(",", list);
}
}

public class CSVSorter
{
public List Header { get; private set; }
public List Data { get; private set; }

public CSVSorter()
{
Data = new List();
}

public void LoadCSV(string filePath, bool hasHeader = true)
{
using (StreamReader sr = new StreamReader(filePath))
{
string line;
bool isFirstLine = true;

while ((line = sr.ReadLine()) != null)
{
List columns = line.Split(',').Select(col => string.IsNullOrWhiteSpace(col) ? null : col).ToList();

if (isFirstLine && hasHeader)
{
Header = columns;
isFirstLine = false;
}
else
{
Data.Add(columns);
if (isFirstLine)
{
isFirstLine = false;
if (!hasHeader)
{
Header = Enumerable.Range(1, columns.Count).Select(i => "Column" + i).ToList();
}
}
}
}
}
}

public void LoadCSV(string fileName, string fileDir, bool hasHeader = true)
{
string filePath = Path.Combine(fileDir, fileName);
LoadCSV(filePath, hasHeader);
}

public void LoadCSV(IEnumerable csvData, bool hasHeader = true)
{
bool isFirstLine = true;

foreach (var columns in csvData)
{
var processedColumns = columns.Select(col => string.IsNullOrWhiteSpace(col) ? null : col).ToList();
if (isFirstLine && hasHeader)
{
Header = processedColumns;
isFirstLine = false;
}
else
{
Data.Add(processedColumns);
if (isFirstLine)
{
isFirstLine = false;
if (!hasHeader)
{
Header = Enumerable.Range(1, processedColumns.Count).Select(i => "Column" + i).ToList();
}
}
}
}
}

public void Sort(int[] columns, SortTypeEnum ascendingOrDescending)
{
try
{
IOrderedEnumerable sortedData = null;

if (ascendingOrDescending == SortTypeEnum.Ascending)
{
sortedData = Data.OrderBy(row => GetColumnValueSafe(row, columns[0]));
for (int i = 1; i < columns.Length; i++)
{
sortedData = sortedData.ThenBy(row =>  GetColumnValueSafe(row, columns[i]));
}
}

Data = sortedData.ToList();
}
catch (Exception ex)
{
Console.WriteLine($"Error during sorting: {ex.Message}");
Console.WriteLine(ex.StackTrace);
}
}

private string GetColumnValueSafe(List row, int columnIndex)
{
return columnIndex < row.Count ? row[columnIndex] : null;
}

public IEnumerable Get()
{
yield return Header;
foreach (var row in Data)
{
yield return row;
}
}

public void SaveCSV(string filePath)
{
using (StreamWriter sw = new StreamWriter(filePath))
{
// Write the header
sw.WriteLine(string.Join(",", Header));

// Write the data rows
foreach (var row in Data)
{
sw.WriteLine(string.Join(",", row.Select(col => col ?? "")));
}
}
}

public void SaveCSV(string fileName, string fileDir)
{
string filePath = Path.Combine(fileDir, fileName);
SaveCSV(filePath);
}
}

class Program
{
static void Main()
{
// Example usage for CSV with potential missing data
CSVSorter sorter = new CSVSorter();
sorter.LoadCSV(@"C:\git\rouse_data~~\[PENULTIMATE]\OUTPUT_CSV\input.csv", true); // Adjust path as needed
sorter.Sort(new int[] { 0,1,2 }, SortTypeEnum.Ascending); // Sort by the second column (e.g., particleVolume) in ascending order
sorter.SaveCSV(@"C:\git\rouse_data~~\[PENULTIMATE]\OUTPUT_CSV\sorted___input.csv");

// Display sorted data
foreach (var row in sorter.Get())
{
Console.WriteLine(string.Join(", ", row));
}
}
}
}
Этот класс не дает желаемого результата.

Код: Выделить всё

Column1,Column2,Column3
C,3,1
B,2,2
A,3,3
C,3,10
B,2,20
A,2,30
C,3,100
B,1,200
A,1,300
Существует ли какая-либо библиотека с открытым исходным кодом для сортировки данных CSV по столбцам?

Подробнее здесь: https://stackoverflow.com/questions/785 ... readsheets
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение
  • Записать список в CSV по столбцам apache poi или commons CSV
    Anonymous » » в форуме JAVA
    0 Ответы
    26 Просмотры
    Последнее сообщение Anonymous
  • Группировать по столбцам и распределять значения по нескольким столбцам на основе значения [дубликат]
    Anonymous » » в форуме Python
    0 Ответы
    26 Просмотры
    Последнее сообщение Anonymous
  • Видим странное поведение при попытке добавить PCF в шейдер карты теней.
    Anonymous » » в форуме C#
    0 Ответы
    15 Просмотры
    Последнее сообщение Anonymous
  • Символ глобальной карты не «видим»: как поделиться глобальной картой из общей библиотеки?
    Anonymous » » в форуме C++
    0 Ответы
    33 Просмотры
    Последнее сообщение Anonymous
  • Видим желтые линии под django.shortcuts в VS CODE
    Anonymous » » в форуме Python
    0 Ответы
    12 Просмотры
    Последнее сообщение Anonymous

Вернуться в «C#»