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項目が 4 つではなく 1 つだけの場合は、LINQ を使用してリストをフラット化し、結果を検索しますList<string>.

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

ネストされたリストごとに複数の文字列項目を含むリストに対して、同様のことができますか?

4

5 に答える 5

6

リストにはすべての文字列がこの順序で含まれている必要がありますか? その後、使用できますEnumerable.SequenceEqual。順序が重要でない場合は、次のように使用Enumerable.AllしますContains

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

補足: 検索しているコレクションをHashSet<T>:

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

Servy が述べたように、2 番目のアプローチは、すべてのアイテムだけでなく、それ以上のアイテムを含むリストを取得することを妨げません。Countそれを確認するためにチェックを追加できます。

于 2013-11-14T16:17:12.867 に答える
2

Containsカスタム等値比較子 ( ) を渡すことができるメソッドのオーバーロードされたバージョンを使用できますIEqualityComparer<T>

于 2013-11-14T16:14:51.177 に答える
2

リストを「平坦化」する 1 つの方法は次のとおりです。

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

のアイテムを 1 つ提供します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 に答える