繁体   English   中英

Linq(或 C# 代码)到自联接表以填充空/空值

[英]Linq (or C# code) to Self join a table to fill null/empty values

假设我有一个列表,其中包含缺少值但匹配 id 的元素(可能会或可能不会丢失,所以我想取非 null 或空的值并将它们放入匹配字段名称中转换的单个元素中如果有几个值不是 null 或单个 null 值(如果没有),则到 IGrouping/列表,

这是一个例子

     public class MyClass 
        { 
            public int vali;
            public string vala;
            public string valb;
            public long? vall;
         }

      var list = new List<MyClass>()
                {
                  new MyClass(){vali= 2,vala=null,valb="how are you",vall=7},
                  new MyClass {vali=3,vala="hi",valb="how are you doing",vall=null},
                  new MyClass{vali=2,vala="hello",valb="how are you",vall=null},
                  new MyClass{vali=3,vala=null,valb=null,vall=8},
                  new MyClass(){vali= 2,vala=null,valb=null,vall=7},
                };

我想得到以下 output

 {2,"hello",string[] {"how are you","how are you" },int[] {7,7} }
 {3 , "hi" , "how are you doing" ,8 },

使用 linq


    list.GroupBy(x=>x.vali).Select(x=>x.FirstOrDefault()).ToList();

返回

 {2,"how are you",null,7},
 {3, "how are you doing",null}

那么我可以使用什么查询或如何实现返回列表(或像 linq 那样的 IGrouping 但编写我自己的算法)

谢谢

尝试以下操作:

    class Program
    {

        static void Main(string[] args)
        {
            var list = new List<MyClass>()
                {
                  new MyClass(){vali= 2,vala=null,valb="how are you",vall=7},
                  new MyClass {vali=3,vala="hi",valb="how are you doing",vall=null},
                  new MyClass{vali=2,vala="hello",valb="how are you",vall=null},
                  new MyClass{vali=3,vala=null,valb=null,vall=8},
                  new MyClass(){vali= 2,vala=null,valb=null,vall=7},
                  new MyClass(){vali= 2,vala=null,valb="how are you",vall=7},
                  new MyClass {vali=3,vala="hi",valb="how are you doing",vall=null},
                  new MyClass{vali=2,vala="hello",valb="how are you",vall=null},
                  new MyClass{vali=3,vala=null,valb=null,vall=8},
                  new MyClass(){vali= 2,vala=null,valb=null,vall=7},
                };

            var results = list.GroupBy(x => x).ToList();
          
        }
    }
    public class MyClass : IEquatable<MyClass>
    {
        public int vali;
        public string vala;
        public string valb;
        public long? vall;

        public bool Equals(MyClass other)
        {
            return
                (this.vali == other.vali) &&
                (this.vala == other.vala) &&
                (this.valb == other.valb) &&
                (this.vall == other.vall);
        }
        public override bool Equals(object obj)
        {
            return Equals(obj as MyClass);
        }
        public override int GetHashCode()
        {
            return (this.vali.ToString() + "^" + this.vala + "^" + this.valb + "^" + this.vall.ToString()).GetHashCode();
        }

    }

我想我找到了我想要的

使用以下查询


     var 

    list2=list.ToDictionary(x=>x).GroupBy(x=>x.Key.vali).Select(x=>new  {  
                      vali =  x.First().Key.vali,
                      vala =   x.Count(v =>  v.Value.vala !=null) > 0  ?x.Where(x=>x.Value.vala!=null).Select(x=>x.Value.vala).ToList() : new List<string> { x.FirstOrDefault(x=>x.Value.vala!=null).Value.vala },
                      valb =  x.Count(v =>  v.Value.valb !=null) > 0  ?x.Where(x=>x.Value.valb!=null).Select(x=>x.Value.valb).ToList() : new List<string> { x.FirstOrDefault(x=>x.Value.valb!=null).Value.valb },
                      vall = x.Count(v =>  v.Value.vall !=null) > 0  ?x.Where(x=>x.Value.vall!=0).Select(x=>x.Value.vall).ToList() : new List<long?> { x.FirstOrDefault().Value.vall },
    
                     }).ToList();

您无法获得混合的 output ,其中一些值具有数组,而另一些值具有单个值。 这都是一种或另一种方式。

在我看来,这可以满足您的要求:

var result =
    list
        .GroupBy(x => x.vali)
        .Select(gxs => new 
        {
            vali = gxs.Key,
            vala = gxs.Select(gx => gx.vala).Where(x => x != null).ToList(),
            valb = gxs.Select(gx => gx.valb).Where(x => x != null).ToList(),
            vall = gxs.Select(gx => gx.vall).Where(x => x != null).ToList(),
        })
        .ToList();

我得到:

结果

否则,要获取单个值,请尝试以下操作:

List<MyClass> result =
    list
        .GroupBy(x => x.vali)
        .Select(gxs => new MyClass()
        {
            vali = gxs.Key,
            vala = gxs.Select(gx => gx.vala).Aggregate((x, y) => x ?? y),
            valb = gxs.Select(gx => gx.valb).Aggregate((x, y) => x ?? y),
            vall = gxs.Select(gx => gx.vall).Aggregate((x, y) => x ?? y),
        })
        .ToList();

使用您的数据,我得到以下结果:

结果

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM