按多个参数列出排序

时间:2013-05-13 20:25:00

标签: c# sorting csv

我有一个.csv,其中包含以下标题和文件中的示例行。

AgentID,Profile,Avatar,In_Time,Out_Time,In_Location,Out_Location,Target_Speed(m/s),Distance_Traveled(m),Congested_Duration(s),Total_Duration(s),LOS_A_Duration(s),LOS_B_Duration(s),LOS_C_Duration(s),LOS_D_Duration(s),LOS_E_Duration(s),LOS_F_Duration(s)
2177,DefaultProfile,DarkGreen_LowPoly,08:00:00,08:00:53,East12SubwayportalActor,EWConcourseportalActor,1.39653,60.2243,5.4,52.8,26.4,23,3.4,0,0,0

我需要按第4列(In_time)对此.csv进行排序,增加时间(08:00:00,08:00:01)和第6列(In_Location)按字母顺序排列(例如东,北等)

到目前为止,我的代码看起来像这样:

List<string> list = new List<string>();
using (StreamReader reader = new StreamReader("JourneyTimes.csv"))
{
    string line;
    while ((line = reader.ReadLine()) != null)
    {
        line.Split(',');
        list.Add(line);
    }

我在.csv中读到并使用逗号分割它(没有其他逗号,所以这不是一个问题)。然后我将每行添加到列表中。我的问题是如何对两个参数和.csv的标题进行排序。

我一直在寻找这一天,我对编程比较陌生,这是我的第一个程序,所以我为我缺乏知识而道歉。

3 个答案:

答案 0 :(得分:5)

您可以使用LINQ OrderBy / ThenBy

e.g。

listOfObjects.OrderBy (c => c.LastName).ThenBy (c => c.FirstName)

但首先,您应该将CSV行映射到某个对象。 要将CSV行映射到对象,您可以预定义某些类型或动态创建它

from line in File.ReadLines(fileName).Skip(1) //header
let columns = line.Split(',') //really basic CSV parsing, consider removing empty entries and supporting quotes
select new
{
  AgentID = columns[0],
  Profile = int.Parse(columns[1]),
  Avatar = float.Parse(columns[2])
  //other properties
}

请注意,与许多其他LINQ方法一样,这两个方法使用deferred execution

答案 1 :(得分:0)

您可以使用DataTable

var lines = File.ReadAllLines("test.csv");
DataTable dt = new DataTable();
var columNames = lines[0].Split(new char[] { ',' });
for (int i = 0; i < columNames.Length; i++)
{
    dt.Columns.Add(columNames[i]);
}

for (int i = 1; i < lines.Length; i++)
{
    dt.Rows.Add(lines[i].Split(new char[] { ',' }));
}

var rows = dt.Rows.Cast<DataRow>();
var result = rows.OrderBy(i => i["In_time"])
    .ThenBy(i => i["In_Location"]);

// sum
var sum = rows.Sum(i => Int32.Parse(i["AgentID"].ToString()));

答案 2 :(得分:0)

您正在处理两个不同的问题。

首先,使用OrderBy,ThenBy

可以在C#中排序两列
public class SpreadsheetExample
{
    public DateTime InTime { get; set; }
    public string InLocation { get; set; }

    public SpreadsheetExample(DateTime inTime, string inLocation)
    {
        InTime = inTime;
        InLocation = inLocation;
    }

    public static List<SpreadsheetExample> LoadMockData()
    {
        int maxMock = 10;
        Random random = new Random();
        var result = new List<SpreadsheetExample>();
        for (int mockCount = 0; mockCount < maxMock; mockCount++)
        {
            var genNumber = random.Next(1, maxMock);
            var genDate = DateTime.Now.AddDays(genNumber);
            result.Add(new SpreadsheetExample(genDate, "Location" + mockCount));
        }

        return result;
    }
}

internal class Class1
{
    private static void Main()
    {
        var mockData = SpreadsheetExample.LoadMockData();
        var orderedResult = mockData.OrderBy(m => m.InTime).ThenBy(m => m.InLocation);//Order, ThenBy can be used to perform ordering of two columns

        foreach (var item in orderedResult)
        {
            Console.WriteLine("{0} : {1}", item.InTime, item.InLocation);
        }
    }
}

现在,您可以解决将数据从Excel迁移到类中的第二个问题。 VSTO正是您所寻找的。网上有很多examples。按照我上面发布的示例。替换您的自定义类代替SpreadSheetExample