Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/297.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 搜索列表的最佳方式是什么<;列表<;字符串>>;?_C#_List_Nested Lists - Fatal编程技术网

C# 搜索列表的最佳方式是什么<;列表<;字符串>>;?

C# 搜索列表的最佳方式是什么<;列表<;字符串>>;?,c#,list,nested-lists,C#,List,Nested Lists,假设我有以下清单: List 1: {{"John", "Doe", "Tall", "Old"}, {"John", "Doe", "Short", "Old"}, {"Jane", "Doe", "Tall", "Young"}, {"Jane", "Doe", "Short", "Old"}} 我想在列表中搜索{“John”,“Doe”,“Short”,“Old”} 搜索这个嵌套列表项并确保我没有得到{“John”、“Doe”、“Toll”、“Old”}的最佳方法是什么 如果嵌套列表只包

假设我有以下清单:

List 1:
{{"John", "Doe", "Tall", "Old"},
{"John", "Doe", "Short", "Old"},
{"Jane", "Doe", "Tall", "Young"},
{"Jane", "Doe", "Short", "Old"}}
我想在列表中搜索{“John”,“Doe”,“Short”,“Old”}

搜索这个嵌套列表项并确保我没有得到{“John”、“Doe”、“Toll”、“Old”}的最佳方法是什么

如果嵌套列表只包含一个
字符串而不是四个
项,我将使用LINQ展平列表并搜索结果
列表。
即:

List<string> newList = oldList.SelectMany(x => x).Distinct().ToList();
newList.Contains("string");
List newList=oldList.SelectMany(x=>x.Distinct().ToList();
包含(“字符串”);

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

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

因此列表必须按该顺序包含所有字符串?然后可以使用
可枚举.SequenceEqual
。如果顺序不重要,请使用可枚举的
。所有带有
都包含
,因此:

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

foreach(List<string> l  in result)
    Console.WriteLine(string.Join(",", l));  // John,Doe,Short,Old
foreach(结果中列出l)
Console.WriteLine(string.Join(“,”,l));//约翰,多伊,矮,老

旁注:如果将正在搜索的集合转换为
哈希集
,则可以使第二种方法更有效:

var name=newhashset(new[]{“John”、“Doe”、“Short”、“Old”});
result=list.Where(l=>l.All(names.Contains)).ToList();
正如Servy所提到的,第二种方法不会阻止您获得包含所有项目的列表,但也包含更多项目。您可以添加一个
计数检查来确保它。

将列表“展平”的一种方法如下:

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");
现在,您可以按如下方式搜索包含:

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");

您可以尝试以下操作:

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();

以下是几种方法:

 [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));
    }
[测试]
使用_字符串_Join()的公共void
{
var l=新列表
{
新名单{“约翰”、“多伊”、“高大”、“老”},
新名单{“约翰”、“多伊”、“短”、“旧”},
新名单{“Jane”、“Doe”、“Toll”、“Young”},
新列表{“Jane”、“Doe”、“Short”、“Old”}
};
var l2=新列表{“John”、“Doe”、“Short”、“Old”};
Assert.That(l.Count(inner=>string.Join(“,”,inner).Equals(string.Join(“,”,l2)))是.EqualTo(1));
}
[测试]
使用_SequenceEqual()的公共无效
{
var l=新列表
{
新名单{“约翰”、“多伊”、“高大”、“老”},
新名单{“约翰”、“多伊”、“短”、“旧”},
新名单{“Jane”、“Doe”、“Toll”、“Young”},
新列表{“Jane”、“Doe”、“Short”、“Old”}
};
var l2=新列表{“John”、“Doe”、“Short”、“Old”};
Assert.That(l.Count(inner=>inner.SequenceEqual(l2)),Is.EqualTo(1));
}

这是一个复杂的示例,或者您处于对象拒绝状态。也就是说,您应该有一个对象来表示FirstName、LastName、Height和Age。对于您的数据来说,这似乎是一种奇怪的格式。但是,如果您希望以这种方式存储它,为什么要将其展平以执行搜索?您可以按原样搜索,而无需创建大量临时对象。@user2586804这是用于测试目的的,没有什么特别之处,因此我尝试使用字符串对象使其保持基本。我希望重用该函数来比较多个嵌套列表,这些嵌套列表可能有4个对象,或者可能有84个对象。我认为,将指定的对象用于我当前的目的会有点过分。@TestK定义一个对象需要几秒钟,编写这个问题可能需要更多的努力。现在忘记可重用性,解决眼前的问题。匿名类型实现平等,因此您可以通过搜索
var myPerson=new{First=“John”,…}。如果有意义的话,你甚至可以在一个
哈希集中这样做;你需要做一些更复杂的事情来解释这个问题。@Servy:说得好,编辑了我的答案,提到了这一点。我认为一个简单的
Count
比较就足够了。不管怎样,它通常足够复杂,我建议创建一个“SetEquals”方法来保存所有逻辑,从而也允许您更改/修复实现。另一种选择是使用
HashSet.CreateSetComparer
为您处理它。这是我个人的喜好。
 [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));
    }