【问题标题】:LINQ to return subset of data grouped into an anonymous typeLINQ 返回分组为匿名类型的数据子集
【发布时间】:2014-06-20 10:06:46
【问题描述】:

我有一个人员列表,我想使用 LINQ(查询语法)来获取一个包含所有名字和所有第二个名字的匿名类型。

如果我要使用 foreach:

var firstNames = new HashSet<string>();
var secondNames = new HashSet<string>();

foreach (Person p in ListOfPersons)
{
  firstNames.Add(p.firstName);
  secondNames.Add(p.secondName);
}

什么是返回匿名类型的等效且高效的 LINQ 语句?例如,allNames.FirstNames 和 allNames.SecondNames。

编辑:当我说高效时,我的意思是它在 ListOfPersons 上循环一次,就像上面的 foreach 示例一样。

编辑 2:名称应该不同;我在 foreach 示例中将 List 更改为 HashSet

【问题讨论】:

  • 问题 - 如果你返回一个匿名类型,为什么你需要 2 个变量,firstNamessecondNames
  • 你是所有的名字还是只是不同的名字?
  • @Enigmativity 好点,是的,不同的名字
  • @cyrus - 然后你的效率就超出了迭代的范围。使用 Atomosk 的解决方案,对于来自真实世界数据库(已被带入内存)的一些数据,我可以提取名称是 10.5 毫秒,但要使它们不同,我需要更进一步41.3 毫秒。迭代原始源两次以生成不同的列表只需要 48.3 毫秒。这是迭代两次优于一次的情况。

标签: c# linq


【解决方案1】:

如果您不想重复 ListOfPersons 两次,我在 linq 中看到它的唯一方法是

var firstNames = new List<string>();
var secondNames = new List<string>();

persons.Aggregate(Tuple.Create(firstNames, secondNames), (tuple, person) =>
{
    tuple.Item1.Add(person.firstName);
    tuple.Item2.Add(person.secondName);
    return tuple;
});

但我认为 foreach 要好得多。

【讨论】:

  • 这将比迭代两次慢得多。
  • 其实这并不慢。在这种情况下,它不会创建临时变量,因此速度更快。
  • @Enigmativity 这取决于人是什么。并非每个IEnumerable 都是List。也许个人的GetEnumerator() 执行一些非常复杂的逻辑。或者它可能会为 2 个不同的调用产生不同的结果。
【解决方案2】:

试试这个:

var AnonList = ListOfPersons.Select(x=> new {firstname = x.firstName, secondname = x.secondName});

【讨论】:

    【解决方案3】:
    var nameList = from l in ListOfPersons
                   select new { FirstName = l.Firstname, Surname = l.Surname};
    

    【讨论】:

      【解决方案4】:

      这个怎么样:

      var allNames = new
      {
          firstNames = new List<string>(),
          secondNames = new List<string>()
      };
      
      listOfPersons.ForEach( p => 
      {
          allNames.firstNames.Add( p.firstName );
          allNames.secondNames.Add( p.secondName );
      } );
      

      【讨论】:

        【解决方案5】:

        直观地反击,这是最有效的:

        var names = new
        {
            firstNames = ListOfPersons.Select(x => x.firstName).Distinct().ToList(),
            secondNames = ListOfPersons.Select(x => x.secondName).Distinct().ToList(),
        };
        

        事实证明,对列表进行两次迭代比在创建更多临时变量时构造一个方法对其进行迭代更有效。我已经对这种事情进行了速度测试,并且多次迭代列表获胜。

        【讨论】:

        • fwiw 如果您查看我的原始答案,我的情况几乎完全相同(请参阅编辑历史记录)并且由于两次迭代而被否决...
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-07-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多