-1

重複を相互に排他的にキャッチしたい。つまり、1番目と3番目のアイテムの両方が重複していること、および1番目と4番目のアイテムが重複していることを示す必要があります。

public class Foo
{
    public String Name { get; set; }
    public String SName { get; set; }
}

class Program
{
    static void Main(string[] args)
    {
        var list = new List<Foo>();
        list.Add(new Foo { Name = "a", SName = "d" });
        list.Add(new Foo { Name = "b", SName = "e" });
        list.Add(new Foo { Name = "c", SName = "a" });
        list.Add(new Foo { Name = "a", SName = "f" });

        // only groups by 1 name
        var duplicates = list.GroupBy(i => i.Name).Where(g => g.Count() > 1).Select(g => g.Key);
    }
}

これはforeachで簡単に実行できることを知っています。学びたいと思います。

4

4 に答える 4

1

したがって、いずれかの列から繰り返される名前の値をすべて取得することから始めます。これは非常に簡単です。

IEnumerable<string> repeatedNames = list.SelectMany(foo => new[] { foo.Name, foo.SName })
    .GroupBy(name => name)
    .Where (g => g.Count () > 1)
    .Select(g => g.Key);

次に、それらの名前をそれぞれ取得し、その値を含むすべてのアイテムを見つけます。最終結果は、それぞれの個別の名前のシーケンスになります。シーケンスは、Fooその値を含むすべてのアイテムです。

IEnumerable<List<Foo>> groupings = repeatedNames .Select(name =>
    list.Where(foo => foo.Name == name || foo.SName == name).ToList());

Lists of Foosのシーケンスではなく、個別の値とシーケンスの両方を持つアイテムのシーケンスにしたい場合は、次のように簡単に追加できます。

var groupings = repeatedNames .Select(name => new
    {
        Name = name,
        Foos = list.Where(foo => foo.Name == name || foo.SName == name).ToList()
    });
于 2012-10-24T20:11:08.467 に答える
0

私はこれを思いついた:

// Will return "a" - one which you already had
var duplicatesBetweenNames = list.GroupBy(i => i.Name)
    .Where(g => g.Count() > 1)
    .Select(g => g.Key).ToArray();

var duplicatedInSName = list.Select(x => x.Name)
    .Intersect(list.Select(x => x.SName));
// Will return "c" - represents Names where in SName is duplicate
var duplicatesBetweenNameAndSName = list
    .Where(f => duplicatedInSName.Contains(f.SName))
    .Select(x=>x.Name).ToArray();
于 2012-10-24T20:33:04.470 に答える
0

発生するインデックスではなく、複製される値だけが必要な場合はSelectMany、グループ化を行う前に、名前を文字列の単一のリストに変換するために使用できます。

var duplicates2 = list.SelectMany(n => new string[] {n.Name, n.SName})
                      .GroupBy(g => g)
                      .Where (g => g.Count () > 1)
                      .Select(g => g.Key)
                      .ToList();

編集:文字列だけでなくオブジェクト が必要Fooな場合は、次のように選択できます。

var duplicates3 = list.Where(n => duplicates2.Contains(n.Name) ||
                                  duplicates2.Contains(n.SName));
于 2012-10-24T20:26:14.223 に答える
0

興味深いスレッドですが、この場合、クエリ構文は非常に表現力豊かだと思いました。

var r = from l in list
        from s in new [] {l.Name,l.SName}
        group s by s into g
        where g.Count() > 1
        select g.Key into u
        from l in list
        where u.Contains(l.Name) || u.Contains(l.SName)
        select l;
于 2012-10-24T20:52:15.047 に答える