【问题标题】:Linq select and add multiple values from the same objectLinq 从同一个对象中选择并添加多个值
【发布时间】:2020-08-27 12:23:31
【问题描述】:

假设我有一个具有两个数字属性的类,我创建了一堆。

public class TwoNumbers
{
    public TwoNumbers(int first, int second)
    {
        First = first;
        Second = second;
    }

    public int First { get; set; }
    public int Second { get; set; }
}

有没有办法使用 LINQ 或 lambda 查询将每个对象的 FirstSecond 添加到整数列表中?例如:

List<TwoNumbers> twoNumbersList = new List<TwoNumbers>()
{
    new TwoNumbers(1,1),
    new TwoNumbers(32,59),
    new TwoNumbers(-12,200),
}

// Can I populate a list of integers upon assignment with a LINQ or lambda query?
List<int> integersVerbose = new List<int>()
foreach (var tn in twoNumbersList)
{
    integersVerbose .Add(tn.First);
    integersVerbose .Add(tn.Second);
}

// Desired syntax
var integersConcise = twoNumbersList. /* some expression */ .ToList(); // Automatically infers type from query

// Print the numbers
integersVerbose.Foreach(x => Console.WriteLine(x));
integersConcise.Foreach(x => Console.WriteLine(x));

// Expected output:
// 1
// 1
// 32
// 59
// -12
// 200 
// 1
// 1
// 32
// 59
// -12
// 200 

我知道有一个 SelectMany 方法,但它在这里似乎没有用,因为我不想从对象中提取集合,我只想要一个带有数字的平面列表。

【问题讨论】:

    标签: c# linq


    【解决方案1】:

    你可以像这样使用SelectMany

    var integersConcise = twoNumbersList.SelectMany(x => new[] { x.First, x.Second });
    

    为了避免数组分配,您可以在 TwoNumbers 类上创建一个 IEnumerable 属性:

    public class TwoNumbers
    {
        //...
    
        public IEnumerable<int> Both { get { yield return First; yield return Second; } }
    }
    
    var integersConcise = twoNumbersList.SelectMany(x => x.Both);
    

    甚至实现IEnumerable&lt;int&gt;:

    public class TwoNumbers : IEnumerable<int>
    {
        //...
    
        public IEnumerator<int> GetEnumerator()
        {
            yield return First;
            yield return Second;
        }
    
        IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
    }
    
    var integersConcise = twoNumbersList.SelectMany(x => x);
    

    【讨论】:

      【解决方案2】:

      如果您将这两个数字投影到一个集合中,您可以使用SelectMany

      List<TwoNumbers> twoNumbersList = new List<TwoNumbers> {
          new TwoNumbers(1,1),
          new TwoNumbers(32,59),
          new TwoNumbers(-12,200),
      };
      
      var results = twoNumbersList.SelectMany(nl => new[] { nl.First, nl.Second });
      

      输出:

      1
      1
      32
      59
      -12
      200

      【讨论】:

        【解决方案3】:

        试试 GroupBy

                    List<int> inputs = new List<int> { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
        
                    List<List<int>> outputs = inputs
                        .Select((x, i) => new { x = x, i = i })
                        .GroupBy(x => x.i / 2)
                        .Select(x => new List<int>() {x.First().x, x.Last().x})
                        .ToList();
        

        【讨论】:

        • 反之亦然,我从TwoNumbers 列表开始,我想从中创建一个整数列表。
        猜你喜欢
        • 1970-01-01
        • 2015-09-25
        • 2010-10-03
        • 1970-01-01
        • 1970-01-01
        • 2016-06-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多