4

我有一个包含许多字符串数组的类。我想要一个通用函数,它可以让我获得List<string>一个给定属性的唯一性。例子:

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

我想要一个通用函数,可以让我List<string>在 List 中获得不同的 Animals?我希望这是通用的,所以我还可以获得一个不同的 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);
    }

注意:这与我之前提出的两个问题有关,但我在合并信息时遇到了麻烦。我之前询问过如何使用 SelectMany (SO 1229897) 进行查询,并分别询问了如何编写一个通用函数,该函数使用 Select 而不是 SelectMany (SO 1278989) 获取列表

4

3 回答 3

19

“每个动物园”

点击

假设你有一个动物园列表:

List<Zoo> zooList = GetZooList();

然后,如果您想从所有动物园中获得不同的动物,您可以通过以下方式应用 SelectMany:

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

如果你经常做这个任务并且想要一个函数来包装这三个调用,你可以这样编写这样一个函数:

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

另一个问题(为什么不能推断类型参数)是string[]没有实现IEnumerable<string>. 将该类型参数更改为,IEnumerable<string>而不是string[]

于 2009-09-03T22:48:54.883 回答
1

最好的方法是HashSet<String>为每个创建一个String[]- 这将过滤掉所有重复项。

由于HashSet<T>有一个接受 a 的构造函数,您可以通过将每个数组传递给构造函数IEnumerable<T>来简单地实例化 a 。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 回答
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 回答