【问题标题】:What are the alternative ways to get list of two properties values [closed]获取两个属性值列表的替代方法是什么[关闭]
【发布时间】:2013-05-15 07:18:19
【问题描述】:

有哪些替代方法可以实现由此产生的相同结果:

myCollection.Select(item => item.FirstValue)
  .Concat(myCollection.Select(item => item.SecondValue)).ToList();

场景是一个名为myCollectionCollection<MyClass>,其中包含MyClass 的实例(见下文)。我想为myCollection 中的每个项目创建一个List<int> 实例,其中包含MyClass.FirstValueMyClass.SecondValue

public class MyClass
{
    public int FirstValue { get; set; }
    public int SecondValue {get; set; }
}

【问题讨论】:

  • 你不能简单地将整数作为列表存储在 MyClass 中吗?
  • 你似乎有一个很好的解决方案。一种可能(尽管略有不同)的替代方法是 myCollection.Select(x => new[] {x.FirstValue, x.SecondValue}).SelectMany(x => x); 请注意,这将交替使用值,而不是先拥有一个然后再拥有另一个。
  • 你已经拥有的东西对我来说看起来不错。为什么需要替代方案?
  • @dtb 只是想要我的启迪的替代品
  • @ƉiamondǤeezeƦ 你特别问“使用 LINQ”,这是为什么呢?由于您评论说您有兴趣学习其他方法来做到这一点,以便您找出哪种方法最有效,我认为可能的答案可能是“不要在此处使用 LINQ”。

标签: c# linq


【解决方案1】:

您可以尝试这样的方法,一个 linqy 单通道解决方案:

private IEnumerable<int> Flatten(MyClass instance )
{
  yield return instance.Value1 ;
  yield return instance.Value2 ;
}

...

List<int> ints = myClasses.SelectMany( x => Flatten(x) ).ToList() ;

Flatten 函数必须是真正的方法,因为您不能在闭包中使用 yield return,以免出现此错误

错误 CS1621:yield 语句不能在匿名方法或 lambda 表达式中使用

我怀疑 Linq 解决方案是否比显而易见的解决方案更好、更简单、更高效、更易于理解或其他任何东西:

List<int> ints = new List<int>() ;
foreach( MyClass item in myClasses )
{
  ints.Add(item.Value1) ;
  ints.Add(item.Value2) ;
}

我非常怀疑 Linq 解决方案会更快。如果您的 MyClass 对象集合可以廉价地报告其大小(例如,不遍历集合),您可以通过将列表预分配到所需大小来进一步优化上述内容:

List<int> ints = new List<int>( 2 * myClasses.Count ) ;
foreach( MyClass item in myClasses )
{
  ints.Add(item.Value1) ;
  ints.Add(item.Value2) ;
}

这将节省每次必须调整列表的后备存储大小时重新分配和复制所需的时间。

【讨论】:

  • 在阅读 Jon Skeet 的回答后,我只是在研究 linq 的成本:stackoverflow.com/questions/333242/…,这让我非常确信 Linq 不是解决这个问题的正确方法。它有一种代码味道。
  • @RussC:如今,Linq 似乎确实是这个街区的时尚小子,人们在某种程度上将 Linq 推得比其他任何东西都好。 Resharper是这里的主要罪人。它总是试图说服我应该让它把任何东西变成一个 Linq 表达式。 Resharper 应该是寻求建议的工具:相反,它有点像 MS Office 助手,主动对接不受欢迎的建议。但我离题了。
【解决方案2】:

关于你最后的评论,他们是 ID,我实际上会从另一个方面完全解决这个问题。

如果您提前知道您的 Class 定义中有两个 ID,请放入一个仅返回 Array 或 Type 的 IEnumerable 的属性。

使用您的示例:

public class MyClass
{
    public int FirstValue { get; set; }
    public int SecondValue {get; set; }

    public int[] IDs
    {
        return new[] { FirstValue, SecondValue };
    }
}

然后收集身份证

List<int> allTheIds = new List<int>();
foreach (var mc in MyClassList)
{
    allTheIds.AddRange(mc.IDs);
}

这可能不是完美的语法,但我目前不在 PC 上进行测试!

但是,在我看来,这是最明智的方法,根据我的经验,我认为将 Linq 用于 linqs 并不是一个好主意。

当然这只是个人意见!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-03-09
    • 1970-01-01
    • 2017-02-05
    • 2010-09-07
    • 1970-01-01
    • 2014-01-16
    • 1970-01-01
    相关资源
    最近更新 更多