我从数组列表中获取一些数据有问题
列表是
日期,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
答案 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);
}
这给出了输出:
我们不需要分组的项目来获取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);
}
这会产生输出: