从C#List <list <string >>查找索引

时间:2019-03-14 17:30:03

标签: c#

我有一个List<List<string>>,它看起来像这样:

[0]
    [0]Elephant 
    [1]26
    [2]Thailand
[1] 
    [0]Elephant 
    [1]40
    [2]Thailand
[2] 
    [0]Ant
    [1]2
    [2]Australia
[3] 
    [0]Camel Red hump
    [1]1
    [2]Nigeria

我想找到在Camel一词中找到的索引,例如:3。

int index= animals.FindIndex(r => r.Contains("Camel"));

但是,上面的代码返回-1。我该如何解决?

3 个答案:

答案 0 :(得分:8)

不可复制:

using System;
using System.Collections.Generic;
public class Program
{
    public static void Main()
    {
        var animals = new List<List<string>>()
        {
            new List<string> { "Elephant", "26", "Thailand" },
            new List<string> { "Elephant", "40", "Thailand" },
            new List<string> { "Ant", "2", "Australia" },
            new List<string> { "Camel", "1", "Nigeria" }
        };
        int index= animals.FindIndex(r => r.Contains("Camel"));
        Console.WriteLine(index);
    }
}

按预期打印3。 您在未显示给我们的代码中做错了。向我们展示失败的代码。 采用上面刚刚写的代码,它是一个完整的程序,您可以剪切并粘贴并执行该程序,然后对其进行修改,以演示您的错误。这样,您将找到该错误,或​​者编写一个程序,让其他人清楚该错误是什么。


更新:问题与所陈述的不同。 将来,请写出描述您实际遇到的问题的问题。这样一来,每个参与人员都不必浪费时间在看错问题上。

真正的问题是:

    var animals = new List<List<string>>()
    {
        new List<string> { "Elephant", "26", "Thailand" },
        new List<string> { "Elephant", "40", "Thailand" },
        new List<string> { "Ant", "2", "Australia" },
        new List<string> { "Camel red hump", "1", "Nigeria" }
    };

我们希望基于查询字符串“ Camel”找到项目3。

这是您解决此问题的方法。首先,您针对单个字符串进行解决:

string test1 = "Foo Bar Blah";
string test2 = "Camel red hump";

我们想要什么?我们想知道“ Camel”是否出现在字符串中。这是通过string.Contains完成的:

Console.WriteLine(test1.Contains("Camel")); // False
Console.WriteLine(test2.Contains("Camel")); // True

好的。我们可以解决单个字符串的问题。现在,为字符串列表解决问题:

var list1 = new List<string> { "Ant", "2", "Australia" };
var list2 = new List<string> { "Camel red hump", "1", "Nigeria" };

我们希望知道谓词string.Contains("Camel")对于list1list2任何成员是否成立。因此,请使用Any

(请记住添加using System.Linq;以使用Any序列方法。)

Console.WriteLine(list1.Any(s => s.Contains("Camel")); // False
Console.WriteLine(list2.Any(s => s.Contains("Camel")); // True

很好,我们现在有一个谓词适用于字符串列表。现在,我们希望将其应用于字符串列表:

var index = animals.FindIndex(
  list => list.Any(
    s => s.Contains("Camel"))); 
// Prints 3

你看到我在那里做什么? 您应该使用的方法来攻击序列中的问题:首先解决单个元素上的问题,然后将该解决方案扩展到元素序列,然后将该解决方案扩展到序列中元素等。从简单的问题逐步发展为更困难的问题。

现在,所有Any可能是使用错误的谓词。如果您有一只动物new List<string>{"Canada Goose", "123", "United States"}和一只动物new List<string>{"Wolverine", "4567", "Canada"},则在寻找加拿大鹅时,有冒险搜寻Canada并发现金刚狼的风险。首先,您可能不应该将此数据表示为List<List<string>>。您应该这样做:

class Animal
{
  public string Kind { get; }
  public int Size { get; }
  public string Country { get; }
  public Animal (string kind, int size, string country)
  {
    this.Kind = kind;
    ... and so on.

现在您可以说:

 var animals = new List<Animal>()
    {
        new Animal("Elephant", 26, "Thailand"),
        new Animal("Elephant", 40, "Thailand"),
        new Animal("Ant", 2, "Australia"),
        new Animal("Camel red hump", 1, "Nigeria")
    };

现在您的测试是:

int index = animals.FindIndex(a => a.Kind.Contains("Camel"));

这更容易理解。 构建代表业务领域中概念的类型。这样一来,您就可以构建看起来像代码中的概念而不是机制的程序。

答案 1 :(得分:1)

所以您想知道列表的某些项目中是否存在字符串的一部分?

int index = animals.FindIndex(r=>r.Any(x=>x.Contains("Camel")));

仅说明一下,您的代码正在搜索完全匹配,但您没有相同的字符串。因此,此答案将搜索第一个列表(FindIndex)的索引,其中至少一个元素(Any)包含(Contains)字符串Camel。请注意,该代码区分大小写。

答案 2 :(得分:1)

@EricLippert答案与往常一样是正确的,但让我尝试多重构一下您的代码。

您有一个字符串列表列表,并且子列表始终包含:

  • 在索引0上是一只动物
  • 在索引1上,一个ID
  • 在索引2上,是一个国家。

如果列表中的每个条目都是这种情况,那么最好使用类来抽象:

public class MyItem
{
    public int Id { get; set; }
    public string Animal { get; set; }
    public string Country { get; set; }
}

然后,您可以将List<List<string>>替换为更有用的类型:List<MyItem>

这样,您可以正确使用linq,例如:

var item = list.First(i => i.Animal.Contains("Camel"));

使用此策略,您无需获取项目索引,之后便需要获取其他值。