【问题标题】:C# LINQ Arrange Multiple Columns Value and Resign to Specific ColumnsC# LINQ 排列多列值并重新分配到特定列
【发布时间】:2020-05-27 19:31:03
【问题描述】:

我已经尝试使用 Foreach 循环,一个新数组并且正在工作,但我想学习并看看是否有更好的方法来使用 LINQ lambda。

我有一张这样的水果桌

public class fruits
{
   string id {get;set;}
   string fruit1 {get;set;}
   string fruit2 {get;set;}
   string fruit3 {get;set;}
}

例如,表格中并非所有水果字段都被填满:

id    fruit1    fruit2    fruit3
1     Apple               Kiwi
2               Lime
3                         Watermelon
4               Oranges   Grapes

需要像这样的输出:

id    fruit1    fruit2    fruit3
1     Apple     Kiwi          
2     Lime          
3     Watermelon                    
4     Oranges   Grapes           

尝试了以下步骤以使其正常工作

  1. foreach 循环遍历水果对象列表
  2. 将fruit1 ,fruit2 ,fruit3 添加到新数组中
  3. 创建一个基于 array.length 的 for 循环,像这样 object fruit [i] 分配值

我想知道是否有更好的方法来使用 LINQ lambda。

谢谢

【问题讨论】:

  • 将水果分配给特定列的规则是什么?
  • #aubury 通过一个特定的列,我的意思是 f1、f2、f3。

标签: c# linq lambda


【解决方案1】:

Linq 的另一种方法

fruits[] output = input.Select(x => {
var items = new[] { x.fruit1, x.fruit2, x.fruit3 }.Where(y => !string.IsNullOrEmpty(y));
                return  new fruits() {
                    id = x.id,
                    fruit1 = items.ElementAtOrDefault(0),
                    fruit2 = items.ElementAtOrDefault(1),
                    fruit3 = items.ElementAtOrDefault(2)
                };}).ToArray();

https://dotnetfiddle.net/OXYWpW


使用循环的 imo 更好的方法

foreach (fruits item in fruitarray)
{
    var columns = new[] { item.fruit1, item.fruit2, item.fruit3 }.Where(y => !string.IsNullOrEmpty(y));
    item.fruit1 = columns.ElementAtOrDefault(0);
    item.fruit2 = columns.ElementAtOrDefault(1);
    item.fruit3 = columns.ElementAtOrDefault(2);
}

https://dotnetfiddle.net/RVhl9n

【讨论】:

    【解决方案2】:

    所以使用ternary conditional operators 看起来像这样,虽然使用循环会更易读。

    list = list.Select(x => new fruits
            {
                id = x.id,
                fruit1 = x.fruit1 ?? x.fruit2 ?? x.fruit3,
                fruit2 = !string.IsNullOrEmpty(x.fruit1) ? (x.fruit2 ?? x.fruit3) : string.IsNullOrEmpty(x.fruit2) ? null : x.fruit3,
                fruit3 = string.IsNullOrEmpty(x.fruit1) || string.IsNullOrEmpty(x.fruit2) ? null : x.fruit3
            }).ToList();
    

    【讨论】:

      【解决方案3】:

      首先我会列出这些水果,这样你就可以对它们做点什么了。最好你将它们存储在一个列表中;

      添加一个属性 fruits 以列表形式返回水果。

      public List<string> fruit
          {
              get { return new List<string> { this.fruit1, this.fruit2, this.fruit3 };}
              set {
                  this.fruit1 = value.ElementAtOrDefault(0);
                  this.fruit2 = value.ElementAtOrDefault(1);
                  this.fruit3 = value.ElementAtOrDefault(2);
              }
          }
      

      因此获取 Fruits 对象的列表:

      List<Fruits> fruitList = {...};
      

      然后你可以删除所有没有的水果,从而创建一个没有空点的列表。

      fruitList.ForEach(s => s.fruits =  s.fruits.Where(x => !string.IsNullOrEmpty(x)).ToList());
      

      但是,此列表可能比之前的列表更短,因为所有空字符串都会被删除。所以我们必须检查适当索引处的值是否仍然存在。我们使用 ElementAtOrDefault 执行此操作,如果索引处没有值,则返回 null。

      但是您必须注意,这不是保存这些对象的可持续方式,因为您需要为您想要连续存储的水果数量的每增加创建更多水果属性。因此,最好将这些水果存储在一个列表中,以规避所有这些问题。

      【讨论】:

        【解决方案4】:

        Linq 操作 SelectSkipFirstOrDefault

        var projection = fruitses.Select(r=> 
            new fruits { 
                id = r.id, 
                fruit1 = new List<string>(){r.fruit1, r.fruit2, r.fruit3}   
                    .FirstOrDefault(s=>!string.IsNullOrEmpty(s)), 
                fruit2 = new List<string>(){r.fruit2, r.fruit3}
                    .Skip(r.fruit1==null?1:0)
                    .Skip(r.fruit2==null?1:0)
                    .FirstOrDefault(s=> !string.IsNullOrEmpty(s)), 
                fruit3 = new List<string>(){r.fruit3}
                    .Skip(r.fruit1==null?1:0)
                    .Skip(r.fruit2==null?1:0)
                    .FirstOrDefault(s=> !string.IsNullOrEmpty(s))
            });
        

        .NET Fiddle here

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2017-12-27
          • 1970-01-01
          • 1970-01-01
          • 2016-11-28
          • 2020-02-18
          • 1970-01-01
          • 2018-03-27
          • 1970-01-01
          相关资源
          最近更新 更多