简体   繁体   English

LINQ 用于多级嵌套集合上的等效for循环,提取索引信息

[英]LINQ for equivalent for-loop on multi-level nested collection, extracting index information

I have an instance variable _foo declared like so -我有一个像这样声明的实例变量_foo -

List< Dictionary<int, HashSet<int> > > _foo;

Yes, it is a messy data structure that is a List of Dictionaries whose key is an integer and its associated value is a HashSet of integers.是的,它是一个混乱的数据结构,它是一个字典列表,其键是 integer,其关联值是整数的 HashSet。

I am wondering whether a LINQ expression could be written that would do the equivalent of this code snippet:我想知道是否可以编写一个 LINQ 表达式来执行与此代码片段等效的操作:

var myList = new List<(int, int, int)>();
for (int xx = 0; xx < _foo.Count; ++xx)
    foreach (var zzyy in _foo[xx])
        if (zzyy.Value.Count == 1)
            myList.Add((xx, zzyy.Value.First, zzyy.Key));

In other words, I would like to capture the indices of the elements in the List whose Dictionary-value (a HashSet) holds only a single value.换句话说,我想捕获 List 中其 Dictionary-value (a HashSet) 仅包含一个值的元素的索引。 Together with this index, I am also capturing the Dictionary-Key and the corresponding sole value within the Dictionary-value.连同这个索引,我还捕获了 Dictionary-Key 和 Dictionary-value 中相应的唯一值。

The foreach can be written as foreach 可以写成

myList.AddRange(_foo[xx]
  .Where(zzyy => zzyy.Value.Count == 1)
  .Select(zzyy => (xx, zzyy.Value.First(), zzyy.Key)));

In my mind the whole thing as a Linq would be在我看来,作为 Linq 的整件事就是

var myList = _foo.SelectMany((d,x) =>
  d.Where(kvp => kvp.Value.Count==1)
    .SelectMany(
      kvp => kvp.Value,
      (kvp, hsv) => (x,kvp.Key,hsv)
    )
).ToList();

..but honestly, I'm not sure it's clearer or more performant than what you have.. ..但老实说,我不确定它是否比您拥有的更清晰或更高效..

Consider that you have what you wrote, and it works, is easy to understand and debug.. whereas having to ask for outside assistance to convert it into a form that is harder to understand means it become much more difficult to debug if the need arises考虑到你有你写的东西,它工作,很容易理解和调试..而不得不寻求外部帮助将它转换成更难理解的形式意味着如果需要,调试会变得更加困难

I did consider that using partial LINQ might help:我确实考虑过使用部分 LINQ 可能会有所帮助:

var myList = new List<(int, int, int)>();
for (int fi = 0; fi < _foo.Count; ++fi)
    foreach (var kvp in _foo[fi].Where(kvp => kvp.Value.Count == 1))
        myList.Add((fi, kvp.Value.First(), kvp.Key));

..but then then it's more wordy. ..但是然后它就更罗嗦了。 You can see another answer that's had a stab at replacing the foreach with something longer and more convoluted您可以看到另一个答案,它试图用更长更复杂的东西替换 foreach

I'd leave it alone, chalk it up to one of those cases where "LINQ is a hammer, but not every problem is a nail".. Perhaps put the time at looking to see if you can reduce this convoluted nested "list of dictionaries of hashsets" data structure you've got into something easier to work with我不理会它,把它归结为“LINQ是一把锤子,但不是每个问题都是钉子”的情况之一。也许花时间看看你是否可以减少这个令人费解的嵌套“列表hashsets 的字典”数据结构,你已经进入了更容易使用的东西

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM