在另一个List<int>中查找List<int>中所有项的索引,使用C# Linq。

4

我有一个类似如下的列表:

List<int> List1= new List<int>(){3,4,5};

还有另一种外观:

List<int> List2 = new List<int>(){1,2,3,4,5,6};

如何使用Linq从List2中获取List1所有索引的数组,如下所示:
var ResultList = {2,3,4};

我不明白,为什么结果是2、3和4? - Willy David Jr
@WillyDavidJr 这些是在List1中搜索项在List2中的基于0的索引。 - StuartLC
我明白了,谢谢 @StuartLC - Willy David Jr
@Karaiden,List2 中是否可以有多个与 List1 中的值相同的实例?如果是这样,您是否想列出所有这些实例? - StuartLC
4个回答

11
var ResultList = List1.Select(x => List2.IndexOf(x));

2

这是一种更长的解决方案,但可以避免对数组进行嵌套循环,如果数组很大,则可能更快(但如果数组很小则可能更慢)。

List<int> List1= new List<int>(){3,4,5};
List<int> List2 = new List<int>(){1,2,3,4,5,6};

var lookup = new Dictionary<int, int>();
for(var i=0; i<List2.Count; i++) {
    lookup[List2[i]] = i;
}

List<int> Result = List1.Select(i => {
    int index;
    return lookup.TryGetValue(i, out index) ? index : -1;
}).ToList();

@caesay 完全取决于使用情况。在实际生产代码中,很多内容都会被抽象到其他可枚举扩展方法中,并且与您的答案一样简洁。 - Samuel Neff
5
我刚刚查看了这个(因为我很好奇),如果你正在处理六位数(约20万个)的项目列表,这个答案就更有效了。 - caesay

1

您还可以使用重载版本的Select语句来选择值并返回索引:

var result = List2.Select((a, b) => new {Value = a, Index = b})
                          .Where(x => List1.Any(d => d == x.Value))
                          .Select(c => c.Index).ToArray();

0
如果您的 List2 包含多个 List1 值(或相等值)类型的实例,则可以使用 Select 的索引重载 查找所有重复项:
var List1= new List<int>(){3,4,5};
var List2 = new List<int>(){1,2,3,4,5,6,1,2,3,5};   

var result = List2.Select((x, idx) => Tuple.Create(x, idx))
    .Where(t => List1.Contains(t.Item1))
    .Select(x => x.Item2)

// 2,3,4,8,9

或者更好的,使用 C#7 值元组

List2.Select((x, idx) => (X:x, Idx:idx))
        .Where(t => List1.Contains(t.X))
        .Select(x => x.Idx);

(.IndexOf 只返回在目标中找到的第一个索引)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接