C# 如何展平表格或连接行?

C# 如何展平表格或连接行?,c#,linq,C#,Linq,有没有一种优雅的方法可以展平C#中的多行(使用Linq或不使用Linq) 假设 var rows = new List<Row> { new Row() { Col1 = 1, Col2 = null ,Col3 = null}, new Row() { Col1 = null, Col2 = 2 ,Col3 = null}, new Row() { Col1 = null, Col2 = null ,Col3 = 3}, new Row() { Col1 =

有没有一种优雅的方法可以展平C#中的多行(使用Linq或不使用Linq)

假设

var rows = new List<Row> {
   new Row() { Col1 = 1, Col2 = null ,Col3 = null},
   new Row() { Col1 = null, Col2 = 2 ,Col3 = null},
   new Row() { Col1 = null, Col2 = null ,Col3 = 3},
   new Row() { Col1 = 2, Col2 = null ,Col3 = null},
};
这将产生

var res = new List<Row> {
   new Row() { Col1 = 1, Col2 = 2 ,Col3 = 3},
   new Row() { Col1 = 2, Col2 = null ,Col3 = null}
   };
var res=新列表{
新行(){Col1=1,Col2=2,Col3=3},
新行(){Col1=2,Col2=null,Col3=null}
};

有什么想法吗?

这可能不是最漂亮的解决方案,但它很有效,并能给你预期的结果

它从原始列表的第一个元素开始构建一个新列表。然后考虑下一项,检查它是否可以用第一项折叠此项,如果可以,则折叠。这会重复,直到它不再能够崩溃。在这种情况下,在结果列表中添加一个新的条目,并且该过程开始,直到它耗尽了要考虑的原始列表。 因为我使用的是反射,所以您可以使用具有任意命名/类型属性的任何类

void Main()
{
    var rows = new List<Row> {
        new Row() { Col1 = 1, Col2 = null, Col3 = null},
        new Row() { Col1 = null, Col2 = 2, Col3 = null},
        new Row() { Col1 = null, Col2 = null, Col3 = 3},
        new Row() { Col1 = 2, Col2 = null, Col3 = null},
    };
    var flattened = rows.Flatten();
}

public static class MyExtensions
{
    public static List<T> Flatten<T>(this List<T> list)
    {
        if (list == null || !list.Any() || list.Count() == 1 || list.First().GetType().GetProperties().Count() == 0)
        {
            return list;
        }

        var index = 0;
        var runner = 0;
        var result = new List<T>();
        do
        {
            result.Add(list[runner]);

            for (int r = runner + 1; r < list.Count; r++)
            {
                if (CanCollapse(result[index], list[r]))
                {
                    Collapse(result[index], list[r]);
                    runner++;
                }
                else
                {
                    break;
                }
            }
            runner++;
            index++;
        } while (runner < list.Count());

        return result;
    }

    private static bool CanCollapse<T>(T target, T next)
    {
        foreach (var p in target.GetType().GetProperties())
        {
            var targetValue = p.GetValue(target, null);
            var nextValue = p.GetValue(next, null);

            if (targetValue != null && nextValue != null && !targetValue.Equals(nextValue))
            {
                return false;
            }
        }
        return true;        
    }

    private static void Collapse<T>(T target, T next)
    {
        foreach (var p in target.GetType().GetProperties())
        {
            var targetValue = p.GetValue(target, null);
            var nextValue = p.GetValue(next, null);

            if (nextValue != null && targetValue == null)
            {
                p.SetValue(target, nextValue);  
            }
        }
    }
}

public class Row
{
    public int? Col1 { get; set; }
    public int? Col2 { get; set; }
    public int? Col3 { get; set; }
}
void Main()
{
变量行=新列表{
新行(){Col1=1,Col2=null,Col3=null},
新行(){Col1=null,Col2=2,Col3=null},
新行(){Col1=null,Col2=null,Col3=3},
新行(){Col1=2,Col2=null,Col3=null},
};
var Flatten=行。flatte();
}
公共静态类MyExtensions
{
公共静态列表展平(此列表)
{
if(list==null | | |!list.Any()| | list.Count()==1 | | list.First().GetType().GetProperties().Count()==0)
{
退货清单;
}
var指数=0;
var=0;
var result=新列表();
做
{
结果。添加(列表[runner]);
for(int r=runner+1;r
你想要实现什么还不是很清楚。第二个版本不是这样展开的,只是将数据移动以删除空值?请给出您的定义好吗?通常,发生在列表列表上。嗨,伙计们,我可能用错了词。。。但是结果是对我试图实现的目标的准确描述。因此,您希望通过垂直向上移动数据来删除所有空值。如果第一行中的Col2不是空值而是2,那么展平规则应该是什么?您是否仍然希望得到与您的问题相同的结果或相同的行数,但Col2=4,或者结果应该有3行?嗨,卡洛·博斯,很抱歉回答得太晚,我正忙于其他工作。。。我会在几天后尝试并更新这篇文章。。。谢谢你事先的努力。。。我真的很感激。我本来会给你留言的,但我没看到option@JosephBartholomew如果上述答案有效,请投票并/或将其标记为解决方案
void Main()
{
    var rows = new List<Row> {
        new Row() { Col1 = 1, Col2 = null, Col3 = null},
        new Row() { Col1 = null, Col2 = 2, Col3 = null},
        new Row() { Col1 = null, Col2 = null, Col3 = 3},
        new Row() { Col1 = 2, Col2 = null, Col3 = null},
    };
    var flattened = rows.Flatten();
}

public static class MyExtensions
{
    public static List<T> Flatten<T>(this List<T> list)
    {
        if (list == null || !list.Any() || list.Count() == 1 || list.First().GetType().GetProperties().Count() == 0)
        {
            return list;
        }

        var index = 0;
        var runner = 0;
        var result = new List<T>();
        do
        {
            result.Add(list[runner]);

            for (int r = runner + 1; r < list.Count; r++)
            {
                if (CanCollapse(result[index], list[r]))
                {
                    Collapse(result[index], list[r]);
                    runner++;
                }
                else
                {
                    break;
                }
            }
            runner++;
            index++;
        } while (runner < list.Count());

        return result;
    }

    private static bool CanCollapse<T>(T target, T next)
    {
        foreach (var p in target.GetType().GetProperties())
        {
            var targetValue = p.GetValue(target, null);
            var nextValue = p.GetValue(next, null);

            if (targetValue != null && nextValue != null && !targetValue.Equals(nextValue))
            {
                return false;
            }
        }
        return true;        
    }

    private static void Collapse<T>(T target, T next)
    {
        foreach (var p in target.GetType().GetProperties())
        {
            var targetValue = p.GetValue(target, null);
            var nextValue = p.GetValue(next, null);

            if (nextValue != null && targetValue == null)
            {
                p.SetValue(target, nextValue);  
            }
        }
    }
}

public class Row
{
    public int? Col1 { get; set; }
    public int? Col2 { get; set; }
    public int? Col3 { get; set; }
}