4

多くの文字列配列を持つクラスがあります。List<string>特定のプロパティに対して一意のものを取得できる汎用関数が 1 つ必要です。例:

public class Zoo 
{    
  string Name { get; set;}
  string[] Animals { get; set;}
  string[] Zookeepers { get; set;}
  string[] Vendors { get; set;}
}

List<string>リスト内の動物を区別する汎用関数が必要ですか? これを一般的なものにしたいので、Zookeepers と Vendors の個別のリストも取得できます。

私はこれを試してきましたが、コンパイルされません:

public static List<string> GetExtendedList(Func<Zoo, string[]> filter)
{
        var Zoos = QueryZoos(HttpContext.Current);
        return Zoos.Where(z => z.Type == "Active")
            .SelectMany(filter)
            .Distinct()
            .OrderBy(s => s);
    }

注: これは以前に尋ねた 2 つの質問に関連していますが、情報を統合するのに問題があります。以前、SelectMany (SO 1229897) を使用してクエリを実行する方法を質問し、SelectManyではなく Select を使用してリストを取得する汎用関数を作成する方法 (SO 1278989) を個別に質問しました。

4

3 に答える 3

19

「各動物園」

クリック

動物園のリストがあるとします。

List<Zoo> zooList = GetZooList();

次に、すべての動物園から異なる動物が必要な場合は、次のようにSelectManyを適用します。

List<string> animalList = zooList
  .SelectMany(zoo => zoo.animals)
  .Distinct()
  .ToList();

また、このタスクを一般的に実行し、1つの関数でこれらの3つの呼び出しをラップしたい場合は、次のようにそのような関数を記述できます。

public static List<string> GetDistinctStringList<T>(
  this IEnumerable<T> source,
  Func<T, IEnumerable<string>> childCollectionFunc
)
{
  return source.SelectMany(childCollectionFunc).Distinct().ToList();
}

これは、次のように呼ばれます。

List<string> animals = ZooList.GetDistinctStringList(zoo => zoo.animals);

また、コンパイルされないコードサンプル(エラーメッセージが表示されていない場合)については、ToList()を追加する必要があると思います。

.OrderBy(s => s).ToList();

もう1つの問題(type引数を推測できない理由)は、をstring[]実装していないことIEnumerable<string>です。そのタイプパラメータをIEnumerable<string>ではなくに変更しますstring[]

于 2009-09-03T22:48:54.883 に答える
1

多分私はあなたが何を意味するのか見落としていますが、単に...

List<String> distinctAnimals = zoo.Animals.Distinct().ToList();

あなたが求めていることをします、私はあなたが何か他のものを意味すると思いますか?

編集:動物園のリストがあるが、個別の動物が必要な場合は、多くを選択するのが正しい使用方法です。IMOは、linq宣言型構文を使用する方が簡単です...

List<String> animals = (from z in zoos
                       from s in z.Animals
                       select s).Distinct().ToList();
于 2009-09-03T22:44:01.807 に答える
1

最善の方法は、HashSet<String>for eachを作成するString[]ことです。これにより、すべての重複が除外されます。

HashSet<T>を受け入れるコンストラクターがあるため、各配列をコンストラクターに渡すIEnumerable<T>ことで単純にインスタンス化できます。HashSet<T>結果HashSet<T>は、の個別のリストになりStringsます。これはList<String>あなたが要求したようなものではありませんが、HashSet<T> 必要ICollection<T>なメソッドの多くを実装している可能性があります。

static ICollection<String> GetDistinct(IEnumerable<String> sequence)
{
    return new HashSet<String>(sequence);
}
于 2009-09-03T22:39:09.417 に答える