【问题标题】:Getting index of duplicate items in a list in c#在C#中获取列表中重复项的索引
【发布时间】:2011-09-24 11:35:23
【问题描述】:

我正在寻找一种方法来从列表中的关键字搜索中获取列表中所有元素的索引。例如,我的清单有:

Hello World
Programming Rocks
Hello
Hello World
I love C#
Hello

现在,我想从这个字符串列表中获取所有显示 Hello World 的元素的索引。我尝试了以下方法,但它只返回它找到的第一个具有我的搜索条件的索引:

    for (int i = 0; i< searchInList.Count; i++)
        foundHelloWorld[i] = searchInList.IndexOf("Hello World");

有人知道怎么做吗?

谢谢

【问题讨论】:

  • 您是否正在寻找包含重复的所有索引的列表,无论内容是什么?更大的图景是什么?
  • 大声笑它不是 hmwk。我有一个可能包含或不包含重复条目的列表。我想要一种方法来确保我们我使用的方法在给我所有索引时考虑了重复的可能性
  • 所以你只想知道列表是否包含指定字符串的重复项,你真的不关心索引吗?

标签: c# list


【解决方案1】:
searchInList.Select((value, index) => new {value, index})
    .Where(a => string.Equals(a.value, "Hello World"))
    .Select(a => a.index)

如果您想搜索的不仅仅是"Hello World",您可以这样做

searchInList.Select((value, index) => new {value, index})
    .Where(a => stringsToSearchFor.Any(s => string.Equals(a.value, s)))
    .Select(a => a.index)

【讨论】:

  • 如果你这样做是为了家庭作业并且他的老师允许 linq 会很有趣:)
  • @Andreas 他会得到荣誉,但实际上,如果他作弊,这将主要伤害他。
  • @Yuriy 抱歉编辑,只是想改进编辑建议...如果您不喜欢它,请随时回复!
  • 我收到一个错误,提示无法将 隐式转换为 int
  • @Ryan 我刚刚尝试过,它可以工作。能否请您发布不起作用的代码?
【解决方案2】:

由于您知道要查找所有匹配项,因此无论如何您都必须遍历整个列表,因此您只需自己检查每个元素,就可以比使用 IndexOf 获得很多可读性:

var i=0;
foreach(var value in searchInList)
{
   if(value == "Hello World")
      foundHelloWorld.Add(i); //foundHelloWorld must be an IList

   i++;
}

您还可以使用 Linq Select 方法的重载,该方法将元素的索引合并到源集合中;对于有 Linq 经验的程序员来说,这应该是高度可读的(因此是可维护的):

foundHelloWorld = searchInList
                     .Select((v,i)=>new {Index = i, Value = v})
                     .Where(x=>x.Value == "Hello World")
                     .Select(x=>x.Index)
                     .ToList();

上面的代码获取列表并将字符串转换为一个简单的匿名类型,其中包含每个项目在原始列表中的位置。然后,它过滤到仅匹配的元素,然后将索引(未通过过滤更改)投影到新的 List 对象中。但是,所有这些转换都会使这个解决方案的执行速度变慢,因为这个语句会多次遍历整个列表。

【讨论】:

  • foreach 和使用 IndexOf 查找所有索引之间没有太大的性能差异;无论如何,必须检查列表中的每个元素是否与搜索字符串相等。所以,如果你需要所有索引,我的观点是不要打扰 IndexOf。
  • 比较 foreach 和 Linq 答案,Linq 答案遍历了 2N+X 个项目,其中 X 是匹配数。首先它转换每个元素,然后检查每个元素是否相等,然后再次转换过滤后的元素。 foreach 只遍历列表一次,从头到尾。因此,Linq 在最佳情况下的执行速度是 foreach 的一半,在最坏情况下的执行速度是 foreach 的三分之一。
  • 不,linq 查询也只会遍历列表一次。
  • Linq 查询将对 N 个元素执行 2N+X 次操作。每个方法都将遍历其整个源可枚举,因此从技术上讲,原始列表被遍历一次,但是第二个和第三个的源,在基数与原始列表相同的情况下,也将被枚举. Foreach 更快;它仅遍历源可枚举对象一次,对每个项目执行一次相等检查。不信,用秒表类测试一下。
  • 没有错,它只会迭代项目一次(与 for 循环中相同)编译查询可能需要一些时间,所以它可能会慢一点。
【解决方案3】:

有点难看,但会起作用:

    var searchInList = new List<string>();

//Populate your list

    string stringToLookUp= "Hello world";
    var foundHelloWorldIndexes = new List<int>();

    for (int i = 0; i < searchInList.Count; i++)
        if (searchInList[i].Equals(stringToLookUp))
            foundHelloWorldIndexes.Add(i);

【讨论】:

    【解决方案4】:

    列表的 FindAll 方法是 here。列表扩展方法here在哪里。

    这两种方法几乎都能满足您的需求,而且它们非常易于使用。互联网上有大量示例,但如果您在使用它们时需要帮助,请告诉我。

    【讨论】:

    • -1:FindAll 和 Where 返回实例,而不是索引。 OP 想知道匹配元素在原始列表中的位置;这两个都只会返回一个只包含匹配项的较短列表。
    猜你喜欢
    • 2011-06-02
    • 1970-01-01
    • 2013-09-25
    • 2023-04-07
    • 1970-01-01
    • 2013-07-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多