考虑一个项目可以临时配对的数据集。
例如,使用徽章登录和退出某个区域时,可能会记录如下数据:
┏━━━━━━━━━━┳━━━━━━━━━┳━━━━━━━━━━━┓
┃ Time ┃ BadgeId ┃ Direction ┃
┣══════════╪═════════╪═══════════┫
┃ 1001930 ┃ A ┃ IN ┃
┣━━━━━━━━━━╋━━━━━━━━━╋━━━━━━━━━━━┫
┃ 1004901 ┃ B ┃ IN ┃
┣━━━━━━━━━━╋━━━━━━━━━╋━━━━━━━━━━━┫
┃ 1005192 ┃ A ┃ OUT ┃
┣━━━━━━━━━━╋━━━━━━━━━╋━━━━━━━━━━━┫
┃ 1012933 ┃ A ┃ IN ┃
┣━━━━━━━━━━╋━━━━━━━━━╋━━━━━━━━━━━┫
┃ 1014495 ┃ B ┃ OUT ┃
┣━━━━━━━━━━╋━━━━━━━━━╋━━━━━━━━━━━┫
┃ 1017891 ┃ A ┃ OUT ┃
┗━━━━━━━━━━┻━━━━━━━━━┻━━━━━━━━━━━┛
然后将其暂时配对以获得类似以下内容:
┏━━━━━━━━━┳━━━━━━━━━━┳━━━━━━━━━━┓
┃ BadgeId ┃ TimeIn ┃ TimeOut ┃
┣═════════╪══════════╪══════════┫
┃ A ┃ 1001930 ┃ 1005192 ┃
┣━━━━━━━━━╋━━━━━━━━━━╋━━━━━━━━━━┫
┃ A ┃ 1012933 ┃ 1017891 ┃
┣━━━━━━━━━╋━━━━━━━━━━╋━━━━━━━━━━┫
┃ B ┃ 1004901 ┃ 1014495 ┃
┗━━━━━━━━━┻━━━━━━━━━━┻━━━━━━━━━━┛
给定一个包含数亿条此类记录的数据集,进行此类时间配对的最有效方法是什么?我对理论上的最佳方法以及使用 LINQ(或其他基于集合的查询语言)的最实际有效的方法感兴趣。
最佳答案
也许这不是处理数百万条记录的最佳理论方法。不过,这是有效的,可以作为进一步改进的起点。
class Program
{
static void Main(string[] args)
{
var StartingRecords = new List<Record>()
{
new Record(1001930, "A", "IN"),
new Record(1004901, "B", "IN"),
new Record(1005192, "A", "OUT"),
new Record(1012933, "A", "IN"),
new Record(1014495, "B", "OUT"),
new Record(1017891, "A", "OUT"),
};
var records = StartingRecords.OrderBy(x => x.BadgeId).ThenBy(x => x.Time).ToList();
var pairs = records.Skip(1).Zip(records, (second, first) => Tuple.Create(first, second)).
Where(x => x.Item1.BadgeId == x.Item2.BadgeId &&
x.Item1.Direction == "IN" && x.Item2.Direction == "OUT").
Select(x => new Pair(x.Item1.BadgeId, x.Item1.Time, x.Item2.Time)).ToList();
foreach (var pair in pairs)
Console.WriteLine(pair.BadgeId + "\t" + pair.TimeIn + "\t" + pair.TimeOut);
Console.Read();
}
}
class Record
{
public long Time { get; set; }
public string BadgeId { get; set; }
public string Direction { get; set; }
public Record(long time, string badgeId, string direction)
{
Time = time;
BadgeId = badgeId;
Direction = direction;
}
}
class Pair
{
public string BadgeId { get; set; }
public long TimeIn { get; set; }
public long TimeOut { get; set; }
public Pair(string badgeId, long timeIn, long timeOut)
{
BadgeId = badgeId;
TimeIn = timeIn;
TimeOut = timeOut;
}
}
输出:
1001930 1005192
1012933 1017891
B 1004901 1014495
关于c# - 使用 LINQ 高效配对时间相关记录,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51155103/