【问题标题】:How to Flatten Table or Concatenate Rows?如何展平表格或连接行?
【发布时间】:2019-10-26 16:00:01
【问题描述】:

是否有一种优雅的方法可以在 C# 中展平多行(使用或不使用 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 = rows.flatten();

这会产生

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

有什么想法吗?

【问题讨论】:

  • 它并不清楚您想要实现什么。第二个版本并没有像这样被展平,只是数据移动了要删除空值?
  • 你能给出"flatten"的定义吗?通常,flattening a list 发生在列表列表中。
  • 大家好,我可能用错了词……但结果是对我想要实现的目标的准确描述。
  • 所以你想通过垂直向上移动数据来删除所有空值
  • 如果第一行的 Col2 不是 null 而是 2,你的展平规则应该是什么?您是否仍然与您的问题相同的结果或相同的行数但 Col2 = 4,或者结果应该有 3 行?

标签: c# linq


【解决方案1】:

这可能不是最漂亮的解决方案,但它可以工作并为您提供预期的结果。

它从原始列表的第一个元素开始构造一个新列表。然后考虑下一个项目,检查它是否可以与第一个项目一起折叠,如果可以,则折叠。如此重复,直到它不再能够崩溃。在这种情况下,将新条目添加到结果列表中,然后流程重新开始,直到用完要考虑的原始项目列表。

由于我使用反射,您可以使用任何具有任意命名/类型属性的类。

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; }
}

【讨论】:

  • 嗨 Carlo Bos,抱歉回复晚了,我正在忙其他工作……我会在几天后尝试并更新这篇文章……提前感谢您的努力。 .. 对此,我真的非常感激。会向您发送消息,但我没有看到该选项
  • @JosephBartholomew 如果上述答案有效,请投票和/或将其标记为解决方案
猜你喜欢
  • 2021-12-01
  • 1970-01-01
  • 1970-01-01
  • 2013-05-24
  • 2010-10-15
  • 1970-01-01
  • 1970-01-01
  • 2017-07-09
  • 1970-01-01
相关资源
最近更新 更多