C# 使用C语言的linqtolookup#

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

我有一个庞大的点数据类型列表和一个同等大小的双列表。规模可能在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
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)}
};
我不知道性能/内存特性会是什么,但我认为它确实提供了您想要的功能

我发现一些文章有助于阐述这个答案:

提供一个Zip的实现,您可以使用

正如我在下面的评论中所说的,我的机器上的性能似乎很好,所以我的机器可能会更快,我的数据可能不会和你的一样,或者我认为“好”的,你可能会认为“慢”。话虽如此,我正在添加一些代码,这些代码可能比您的版本性能更好(也可能不是)。如果这还不够,我不知道还能补充什么。另外,在你最初的问题中,你说你的内存用完了。我建议的代码仍然会发生这种情况吗

我对您的代码的重写:

//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);
}