使用c#

时间:2017-07-28 22:02:27

标签: c#

我从数组列表中获取一些数据有问题

列表是

日期,ID,出价,时间,通话,ST

2017-07-26 23:53:14,15a4ca7e,13,274,265,OK
2017-07-26 23:56:11,14f418a8,29,131,108,OK
2017-07-26 23:55:59,14df675e,31,189,168,OK
2017-07-26 23:56:54,1557ff5c,30,155,155,OK
2017-07-26 23:55:56,158db0b1,04,221,219,OK
2017-07-26 23:57:48,155a9e93,39,118,110,OK
2017-07-26 23:59:08,15aa6a2c,30,44,23,OK
2017-07-27 00:00:16,1596cd53,66,0,0,BUSY
2017-07-26 23:59:37,15aa68bc,30,61,51,OK
2017-07-27 00:00:10,150994b8,66,30,0,BUSY
2017-07-26 23:59:59,15aa6a2c,41,45,14,OK
2017-07-26 23:53:50,14df706d,02,420,419,OK
2017-07-26 23:57:32,14d5b722,22,205,192,OK
2017-07-26 23:58:00,150ff690,35,194,187,OK
2017-07-27 00:00:57,15aa6a2c,44,51,38,OK
2017-07-27 00:01:04,15a4afb7,30,49,48,OK
2017-07-27 00:00:32,15a1c53f,04,85,77,OK
2017-07-27 00:00:46,159fb87c,31,102,94,OK
2017-07-27 00:02:27,15590a6b,02,19,18,OK
2017-07-26 23:59:26,14fa65b7,16,201,178,OK
2017-07-27 00:02:42,15aa6a55,35,52,51,OK

这是我的代码

    private List<ColList> colListItems = new List<ColList>();
    public List<ColList> readData(string filePath)
    {

        StreamReader sr = new StreamReader(filePath);

        foreach (string readLine in sr.ReadToEnd().Split('\n'))
        {
            if (readLine != "")
            {
                string[] line = readLine.Split(',');
                colListItems.Add(new ColList()
                {
                    date = line[0],
                    id = line[1],
                    bid = int.Parse(line[2]),
                    time = int.Parse(line[3]),
                    talk = int.Parse(line[4]),
                    st = line[5]

                });
            }
        }

        return colListItems;
    }


public class ColList
{
    public string date;
    public string id;
    public int bid;
    public int time;
    public int talk;
    public string st;
}

我想从上表中查看具有最大(时间)的(id),但必须在获得(id)唯一的最大时间之前将(时间)相加

重复这个(id)(15aa6a2c)所以我将(时间)相加并将他的行分成1行,如果有任何重复的行,我将总和(时间)&amp; (谈话)这样的专栏

2017-07-26 23:59:08    15aa6a2c    30    44    23    OK
2017-07-26 23:59:59    15aa6a2c    41    45    14    OK
2017-07-27 00:00:57    15aa6a2c    44    51    38    OK

它将是

2017-07-27 00:00:57    15aa6a2c    0    140    75    OK

并且需要知道(id)反复多少次     for(id)它重复了3次

什么是最大和最低的(出价)取决于(st == OK)&amp;&amp; (st!= OK)通过计算

为此要求它就像这样(30)有4行依赖于st == OK和(22)有1行

2017-07-27 00:01:04    15a4afb7    30    49    48    OK
2017-07-26 23:59:08    15aa6a2c    30    44    23    OK
2017-07-26 23:56:54    1557ff5c    30    155    155    OK
2017-07-26 23:59:37    15aa68bc    30    61    51    OK

2017-07-26 23:58:00    150ff690    35    194    187    OK
2017-07-27 00:02:42    15aa6a55    35    52    51    OK


2017-07-26 23:59:59    15aa6a2c    41    45    14    OK
2017-07-27 00:00:57    15aa6a2c    44    51    38    OK


2017-07-26 23:53:50    14df706d    02    420    419    OK
2017-07-27 00:02:27    15590a6b    02    19    18    OK


2017-07-26 23:55:56    158db0b1    04    221    219    OK
2017-07-27 00:00:32    15a1c53f    04    85    77    OK

2017-07-27 00:00:46    159fb87c    31    102    94    OK
2017-07-26 23:55:59    14df675e    31    189    168    OK

2017-07-26 23:57:32    14d5b722    22    205    192    OK

1 个答案:

答案 0 :(得分:1)

通常,您似乎希望使用GroupBy方法按Id对项目进行分组,然后找到符合某些条件的项目。

以下是一个示例,该示例应满足在获取具有相同Id的所有项目的谈话总和之后找到具有最大谈话价值的ID的要求:

/// <summary>
/// Will return an item with the Id and Time for the items
/// in the list that have the max Sum(Time) for that id
/// </summary>
/// <param name="input">A list of items to search</param>
/// <returns>A new item representing the Id with the Max(Sum(Time))</returns>
public static ColList GetIdWithMaxTime(List<ColList> input)
{
    // Argument validation
    if (input == null || !input.Any())
    {
        throw new ArgumentException("The input list must contain at least one item");
    }

    // Group items by Id, and select new items with the 
    // 'Time' field set to the sum of those for that Id
    var inputGroupedById = input
        .GroupBy(item => item.Id)
        .Select(i => new ColList
        {
            Date = i.Max(item => item.Date),
            Id = i.Key,
            Time = i.Sum(item => item.Time),
            Talk = i.Sum(item => item.Talk),
            St = i.First().St
        })
        .ToList();

    // Return the first one whose Time equals the Max(Time)
    return inputGroupedById.First(i => i.Time == inputGroupedById.Max(g => g.Time));
}

这是另一种可能也有帮助的方法。我创建了一个方法,返回整个列表,按Id分组,以及Talk和时间总和的总和:

/// <summary>
/// Will a list of all items grouped by the Id, 
/// with a Sum of the Time and Talk fields
/// </summary>
/// <param name="input">A list of items to search</param>
/// <returns>A new item representing the Id with the Max(Sum(Time))</returns>
public static List<ColList> GroupItemsOnId(List<ColList> input)
{
    // Argument validation
    if (input == null || !input.Any())
    {
        throw new ArgumentException("The input list must contain at least one item");
    }

    // Group items by Id and select the sum for Time and Talk
    return input
        .GroupBy(item => item.Id)
        .Select(i => new ColList
        {
            Date = i.Max(item => item.Date),
            Id = i.Key,
            Time = i.Sum(item => item.Time),
            Talk = i.Sum(item => item.Talk),
            Status = i.First().Status
        })
        .ToList();
}

我也稍微更改了您的课程,添加了ToString()覆盖,以便我们能够以一致的方式输出项目:

public class ColList
{
    public string Date { get; set; }
    public string Id { get; set; }
    public int BId { get; set; }
    public int Time { get; set; }
    public int Talk { get; set; }
    public string Status { get; set; }

    public override string ToString()
    {
        return $"{Date}\t{Id}\t{BId}\t{Time}\t{Talk}\t{Status}";
    }
}

我也使用这种方法来解析文本文件,这与你的类似,但有一些错误处理:

public static List<ColList> GetData(string filePath)
{
    var data = new List<ColList>();
    if (filePath == null || !File.Exists(filePath)) return data;
    var fileLines = File.ReadAllLines(filePath).Where(line => !string.IsNullOrEmpty(line));

    foreach (var fileLine in fileLines)
    {
        var lineParts = fileLine.Split(',');
        int tmp;
        data.Add(new ColList()
        {
            Date = lineParts[0],
            Id = lineParts.Length > 0 ? lineParts[1] : "",
            BId = lineParts.Length > 1 && int.TryParse(lineParts[2], out tmp) ? tmp : 0,
            Time = lineParts.Length > 2 && int.TryParse(lineParts[3], out tmp) ? tmp : 0,
            Talk = lineParts.Length > 3 && int.TryParse(lineParts[4], out tmp) ? tmp : 0,
            Status = lineParts.Length > 4 ? lineParts[5] : ""
        });
    }

    return data;
}

现在我们可以使用这个新方法获取所有项目的列表,按ID分组:

// Populate our colListItems list and get grouped items
var filePath = @"f:\public\temp\temp.txt";
var items = GetData(filePath);
var groupedItems = GroupItemsOnId(items);

现在我们可以通过按时间或通过谈话对订购的项目进行排序来显示我们的数据:

Console.WriteLine("Here are the items sorted by Time, followed by the times the Id repeated:");
foreach (var item in groupedItems.OrderByDescending(i => i.Time))
{
    // Get the count of this id, and if it was repeated more than once color the text green
    var countOfThisId = items.Count(i => i.Id == item.Id);
    var consoleColor = countOfThisId > 1 ? ConsoleColor.Green : Console.ForegroundColor;
    Console.ForegroundColor = consoleColor;

    Console.WriteLine($"{item}\tId was repeated {countOfThisId} times.");

    Console.ResetColor();
}

Console.WriteLine("\nHere are the items sorted by Talk:");
foreach (var item in groupedItems.OrderByDescending(i => i.Talk))
{
    Console.WriteLine(item);
}

这给出了输出:

enter image description here

我们不需要分组的项目来获取BId结果。相反,我们可以在Status == "OK"上过滤原始列表,然后在OrderByDescending字段上使用BId来排序结果:

// Order our results on 'BId' field           
Console.WriteLine("\nHere are the results ordered by BId where status is 'OK':");
int lastBid = 0;

foreach (var item in items.Where(i => 
    i.Status.Equals("OK")).OrderByDescending(i => i.BId))
{
    // Put a blank line between groups of BIds
    if (item.BId != lastBid)
    {
        Console.WriteLine();
        lastBid = item.BId;
    }

    Console.WriteLine(item);
}

这会产生输出:

enter image description here