从列表中获取包含可能重复项的特定项目的索引

时间:2011-07-09 22:11:14

标签: c# search indexing

好的,我有一个类对象列表,如下所示:     

List<fruit> lst = new List<fruit>();
    lst.Add(orange);
    lst.Add(apple);
    lst.Add(grape);
    lst.Add(grape);
    lst.Add(orange);
    lst.Add(pear);
    lst.Add(apple);

我希望能够在列表中查询类似的内容 GetIndex(“orange”,2)并让它返回(在本例中)第二个对象实例的索引#(位置4)。

此列表将动态填充,甚至可能没有橙色开头。如果是,我想要第二个参数的实例号。所以我可以得到第二个橙子,或者得到第五个芒果等等。

list.IndexOf(orange)返回任何重复项的第一个实例,所以我需要别的东西。

有什么想法吗?

PS:我没有提到第一个参数将是一个字符串!

6 个答案:

答案 0 :(得分:3)

public static int GetIndex<T>(this IEnumerable<T> lst, T obj, int index)
{
    return lst.Select((o, i) => new { o, i })
              .Where(x => x.o.Equals(obj))
              .ElementAt(index - 1)
              .i;
}

尽管index从1开始有点奇怪,但结果从0开始。

答案 1 :(得分:2)

        int index = lst.IndexOf(orange);
        if (index >= 0)
        {
            index = lst.IndexOf(orange, index + 1);
        }

或者为了使它通用,你可以使用一些LINQ:

    static int GetIndex(IEnumerable<Fruit> li, Fruit ob, int k)
    {
        var tmp = li.Select((it, i) => new Tuple<int, Fruit>(i, it)).Where(tup => tup.Item2 == ob).Skip(k - 1).FirstOrDefault();
        if (tmp == null)
            return -1;
        else 
            return tmp.Item1;
    }

然后拨打GetIndex(lst, orange, 2)

答案 2 :(得分:2)

这是我刚写完的通用扩展搜索:

public static class ListExtension
{
    public static int GetIndex<T>(this List<T> entity, T what, int find)
    {
        int found = 0;
        int index = -1;

        while ((index = entity.IndexOf(what, (index + 1))) != -1)
        {
            found++;

            if (found == find)
                break;
        }

        return (index);
    }
}

你所要做的就是这样称呼它:

int index = lst.GetIndex(apple, 2);

如果找不到您要查找的项目,则返回-1。

答案 3 :(得分:1)

var result = list.Select((x, i) => new { x, i })
                  .Where(t => t.x == fruit)
                  .Skip(k - 1)
                  .Select(t => t.i)
                  .First();

答案 4 :(得分:1)

您可以使用自己的方法为该类扩展类,遗憾的是,这对于泛型类是不可能的,因此您可以使用该方法为类型提供。

public static class ListExtension
{
    public static int GetIndex<T>(this List<T> list, T value, int skipMatches = 1)
    {
        for (int i = 0; i < list.Count; i++)
            if (list[i].Equals(value))
            {
                skipMatches--;
                if (skipMatches == 0)
                    return i;
            }
        return -1;
    }
}

List<int> list = new List<int>();
list.Add(3);
list.Add(4);
list.Add(5);
list.Add(4);
int secondFour = (int)list.GetIndex(4, 2);

答案 5 :(得分:0)

当你找不到你正在寻找的价值时,dtb答案的延伸:

public int GetIndex<T>(IEnumerable<T> list, T item, int itemNum) {
    // result is a nullable int containing the index
    var result = list.Select((x, i) => new { x, i })
                     .Where(t => item.Equals(t.x))
                     .Skip(itemNum - 1)
                     .Select(t => (int?)t.i)
                     .FirstOrDefault();
    // return -1 when item was not found
    return (result.HasValue ? result.Value : -1);
}