1

データ構造から始めます。

class Device
{
   public List<string> Interfaces { get; set; }
}

List<Device> allDevices;

Linq クエリを使用して、allDevices リストの各デバイスに存在するすべてのインターフェイス (文字列) を選択したいと考えています。

事前に感謝します。

更新: Aron のおかげで、この問題を解決できました。これが私の解決策です:

List<string> commonInterfaces = allDevices.Select(device => device.Interfaces)
   .Cast<IEnumerable<string>>()
   .Aggregate(Enumerable.Intersect)
   .ToList();
4

3 に答える 3

5

Enumerable.Intersectたとえば、次のように使用できます。

IEnumerable<string> commonSubset = allDevices.First().Interfaces;
foreach (var interfaces in allDevices.Skip(1).Select(d => d.Interfaces))
{
    commonSubset = commonSubset.Intersect(interfaces);
    if (!commonSubset.Any())
        break;
}

DEMO

再利用したい場合は、拡張メソッドにすることができます。

public static IEnumerable<T> CommonSubset<T>(this IEnumerable<IEnumerable<T>> sequences)
{
    return CommonSubset(sequences,  EqualityComparer<T>.Default);
}

public static IEnumerable<T> CommonSubset<T>(this IEnumerable<IEnumerable<T>> sequences, EqualityComparer<T> comparer)
{
    if (sequences == null) throw new ArgumentNullException("sequences");
    if (!sequences.Any()) throw new ArgumentException("Sequences must not be empty", "sequences");

    IEnumerable<T> commonSubset = sequences.First();
    foreach (var sequence in sequences.Skip(1))
    {
        commonSubset = commonSubset.Intersect(sequence, comparer);
        if (!commonSubset.Any())
            break;
    }
    return commonSubset;
}

これで、使用法は非常に簡単になりました (コンペアラーはカスタム型に使用できます)。

var allInterfaces = allDevices.Select(d => d.Interfaces);
var commonInterfaces = allInterfaces.CommonSubset();
Console.Write(string.Join(",", commonInterfaces));
于 2013-08-28T13:14:27.140 に答える