2

假设我有以下列表:

List 1:
{{"John", "Doe", "Tall", "Old"},
{"John", "Doe", "Short", "Old"},
{"Jane", "Doe", "Tall", "Young"},
{"Jane", "Doe", "Short", "Old"}}

我想在列表中搜索{“John”、“Doe”、“Short”、“Old”}。

搜索此嵌套列表条目并确保我没有得到 {"John", "Doe", "Tall", "Old"} 的最佳方法是什么?

如果嵌套列表只包含string一项而不是四项,我将使用 LINQ 展平列表并搜索结果,List<string>.即:

List<string> newList = oldList.SelectMany(x => x).Distinct().ToList();
newList.Contains("string");

对于每个嵌套列表包含多个字符串项的列表,我可以做类似的事情吗?

4

5 回答 5

6

所以列表必须包含该顺序的所有字符串?然后你可以使用Enumerable.SequenceEqual. 如果顺序不重要,请使用Enumerable.AllContains所以:

var names = new[]{"John", "Doe", "Short", "Old"};
List<List<string>> result = list
    .Where(l => l.SequenceEqual(names)).ToList();

或者

result = list
    .Where(l => l.All(name => names.Contains(name))).ToList();

输出:

foreach(List<string> l  in result)
    Console.WriteLine(string.Join(",", l));  // John,Doe,Short,Old

Demo

旁注:如果将要搜索的集合转换为 a ,则可以使第二种方法更有效HashSet<T>

var names = new HashSet<string>(new[]{"John", "Doe", "Short", "Old"});
result = list.Where(l => l.All(names.Contains)).ToList();

正如 Servy 所提到的,第二种方法不会阻止您获取包含所有项目但还包含更多项目的列表。您可以添加Count检查以确保它。

于 2013-11-14T16:17:12.867 回答
2

您可以使用Contains允许传递自定义相等比较器 ( IEqualityComparer<T>) 的方法的重载版本。

于 2013-11-14T16:14:51.177 回答
2

“扁平化”列表的一种方法如下:

var people = list1.
    Select(lst => new {
        First  = lst[0]
    ,   Last   = lst[1]
    ,   Height = lst[2]
    ,   Age    = lst[3]
    });

现在您可以按如下方式搜索遏制:

bool hasShortOldJohnDoe = people
    .Contains(p => p.First=="John"
                && p.Last=="Doe"
                && p.Height == "Short"
                && p.Age=="Old");
于 2013-11-14T16:17:20.500 回答
1

您可以尝试以下方法:

List<List<string>> mainList = new List<List<string>>

{
    new List<string>(){"John", "Doe", "Tall", "Old"},
    new List<string>(){"John", "Doe", "Short", "Old"},
    new List<string>(){"Jane", "Doe", "Tall", "Young"},
    new List<string>(){"Jane", "Doe", "Short", "Old"},
};
List<string> searchList = new List<string>() { "John", "Doe", "Short", "Old" };

var temp = mainList[0].Except(searchList).Count();
List<List<string>> result  = mainList
                                .Where(r => r.Except(searchList).Count() == 0)
                                .ToList();

它会给你一个项目result

或者:

var  result = mainList
                  .Where(r => !r.Except(searchList).Any());
于 2013-11-14T16:29:46.710 回答
1

这里有几种方法:

 [Test]
    public void Using_String_Join()
    {
        var l = new List<List<string>>
        {
            new List<string> {"John", "Doe", "Tall", "Old"},
            new List<string> {"John", "Doe", "Short", "Old"},
            new List<string> {"Jane", "Doe", "Tall", "Young"},
            new List<string> {"Jane", "Doe", "Short", "Old"}
        };

        var l2 = new List<string> {"John", "Doe", "Short", "Old"};

        Assert.That(l.Count(inner => string.Join(",", inner).Equals(string.Join(",", l2))), Is.EqualTo(1));
    }

    [Test]
    public void Using_SequenceEqual()
    {
        var l = new List<List<string>>
        {
            new List<string> {"John", "Doe", "Tall", "Old"},
            new List<string> {"John", "Doe", "Short", "Old"},
            new List<string> {"Jane", "Doe", "Tall", "Young"},
            new List<string> {"Jane", "Doe", "Short", "Old"}
        };

        var l2 = new List<string> {"John", "Doe", "Short", "Old"};

        Assert.That(l.Count(inner => inner.SequenceEqual(l2)), Is.EqualTo(1));
    }
于 2013-11-14T16:32:00.680 回答