C# 使用C语言的linqtolookup#
我有一个庞大的点数据类型列表和一个同等大小的双列表。规模可能在1000000左右。两个列表都来自不同的类C# 使用C语言的linqtolookup#,c#,linq,lookup,C#,Linq,Lookup,我有一个庞大的点数据类型列表和一个同等大小的双列表。规模可能在1000000左右。两个列表都来自不同的类 List<Point> XYPair; E.g. { (10,10),(10,10).......(20,20),(20,20).....} List<double> ZValue; E.g. { 1.5, 1.6, .............7.8,8.7......} 你为什么需要林克?只需使用一个循环: // Prepare the dictionary D
List<Point> XYPair; E.g. { (10,10),(10,10).......(20,20),(20,20).....}
List<double> ZValue; E.g. { 1.5, 1.6, .............7.8,8.7......}
你为什么需要林克?只需使用一个循环:
// Prepare the dictionary
Dictionary<Key, List<double>> dic = new Dictionary<Key, List<double>>();
for (int i =0; i< XYPair.Count; i++){
// Create the key
// Put ZValue[i] values in dictionary list element
}
// Use the Dictionary:
// Loop around dic keys
// If matched, apply statistics
//准备字典
Dictionary dic=新字典();
对于(int i=0;i
如果你做了这样的事怎么办
收集你的观点
var XY = new List<Point>()
{
{ new Point(0, 0) },
{ new Point(10, 20) },
{ new Point(15, 5)},
{ new Point(0,0)},
{ new Point(10,20)}
};
我不知道性能/内存特性会是什么,但我认为它确实提供了您想要的功能
我发现一些文章有助于阐述这个答案:
//Gather your position data
var XY = new List<Point>();
{
{ new Point(0, 0) },
{ new Point(10, 20) },
{ new Point(15, 5)},
{ new Point(0,0)},
{ new Point(10,20)}
};
//Gather your Z values ..
var Z = new List<double>() { 0, 10, 20, 30, 40 };
//Build the lookup
var lookup = XY.Zip(Z, (xy, z) => new { Point = xy, Z = z }).ToLookup(k => k.Point, v => v.Z);
//Process...
//foreach unique XY (the Key of the lookup)
// Check to see if the XY is in a set of MatchingIndexes. If not, continue.
// Add the unique point to the chart series.
// Get the Z values that correspond to the key (no need for ToList unless ApplyStatistics needs something more specialized than IEnumerable).
// Apply the Z values by calling ApplyStatistics
//
foreach (g in lookup.Select(g => g.Key))
{
var matched = MatchingIndexes.Select(i => i == g);
if (!matched.Any()) continue;
chart1.Series[0].Points.AddXY(g.X, g.Y);
var singleZGroup = lookup[g];
ApplyStatistics(singleZGroup);
}
//收集您的位置数据
var XY=新列表();
{
{新点(0,0)},
{新点(10,20)},
{新的点(15,5)},
{新点(0,0)},
{新点(10,20)}
};
//收集你的Z值。。
var Z=新列表(){0,10,20,30,40};
//构建查找
var lookup=XY.Zip(Z,(XY,Z)=>new{Point=XY,Z=Z}).ToLookup(k=>k.Point,v=>v.Z);
//过程。。。
//foreach唯一XY(查找的键)
//检查XY是否在一组匹配索引中。如果没有,请继续。
//将唯一点添加到图表系列中。
//获取对应于键的Z值(不需要ToList,除非ApplyStatistics需要比IEnumerable更专业的东西)。
//通过调用ApplyStatistics应用Z值
//
foreach(查找中的g.Select(g=>g.Key))
{
var matched=matchingindex.Select(i=>i==g);
如果(!matched.Any())继续;
图1.系列[0].点.AddXY(g.X,g.Y);
var singleZGroup=lookup[g];
应用统计学(singleZGroup);
}
注意,我没有测试上面的处理代码。我希望它能工作,并且我希望它能做与您在原始代码中所做的相同的工作。我没有任何特别的期望,这将是“快”或不。我的代码的主要目标是最小化数据的复制次数(通常是通过调用ToList)
祝你好运,我希望这会有所帮助。XYPair与ZValue的比例是1:1吗?换句话说,ZValue[0]是否应用于XYPair[0],ZValue[1]是否应用于XYPair[1],依此类推?另外,我不明白你的GroupedPlotValues=。。。代码之所以这样做,是因为代码中引用的类型似乎与问题开头的类型(XYPair和ZValue)不相关。是的!!!XYPair将1:1与ZValue匹配。GroupedPlotValues正在创建一个具有一个xy键和多个对应ZValue索引的字典。稍后的代码,即singleZGroup获取匹配索引的相应值。为了避免内存不足异常,您必须避免将所有数据加载到内存中。我使用的是VS2008。所以ZIP不可用。我被指示使用hashset。但是我不知道如何使用它。我添加了一个指向Zip实现的链接,您可以使用该链接在.Net.Wageoghe的4.0之前版本上获取Zip。我已经尝试了您的代码。处理lambda查询所用的时间几乎与处理lambda查询所用的时间相同。如果有那么多元素(1000000左右),则需要一些时间。在我的机器上,我能够创建一个包含1000000个点和1000000个Z值的列表,按照上面的(var lookup=…)行执行查询,并在很短的时间内(通过对结果进行交互并计算唯一键的数量)对其进行实际评估(我没有计时,但在调试时没有明显的暂停)。我无法准确复制您正在做的事情,因为我对您如何处理GroupedPlotValues了解不够…我确实有一些问题/建议。。。当您设置matched时,您可能不必调用ToList()(它生成数据的副本)。什么是匹配索引?有多少条?创建singleZGroup时,您可能不必调用ToList()
var Z = new List<double>() { 0, 10, 20, 30, 40 };
var lookup = XY.Zip(Z, (xy, z) => new { Point = xy, Z = z }).ToLookup(k => k.Point, v => v.Z);
//Gather your position data
var XY = new List<Point>();
{
{ new Point(0, 0) },
{ new Point(10, 20) },
{ new Point(15, 5)},
{ new Point(0,0)},
{ new Point(10,20)}
};
//Gather your Z values ..
var Z = new List<double>() { 0, 10, 20, 30, 40 };
//Build the lookup
var lookup = XY.Zip(Z, (xy, z) => new { Point = xy, Z = z }).ToLookup(k => k.Point, v => v.Z);
//Process...
//foreach unique XY (the Key of the lookup)
// Check to see if the XY is in a set of MatchingIndexes. If not, continue.
// Add the unique point to the chart series.
// Get the Z values that correspond to the key (no need for ToList unless ApplyStatistics needs something more specialized than IEnumerable).
// Apply the Z values by calling ApplyStatistics
//
foreach (g in lookup.Select(g => g.Key))
{
var matched = MatchingIndexes.Select(i => i == g);
if (!matched.Any()) continue;
chart1.Series[0].Points.AddXY(g.X, g.Y);
var singleZGroup = lookup[g];
ApplyStatistics(singleZGroup);
}