• 一个简单的Linq to TreeNode


      最近两天写单元测试,碰到需要验证一个树是否是期望的,但是树这个结构要验证起来还真是有点烦。。。

      我的树大概是这样的:

     1 class TreeNode<T>
     2 {
     3         private static readonly TreeNode<T>[] Empty = new TreeNode<T>[0];
     4         public TreeNode() : this(default(T), Empty) { }
     5         public TreeNode(T value, IReadOnlyList<TreeNode<T>> children)
     6         {
     7             Value = value;
     8             Children = children;
     9         }
    10         public T Value { get; set; }
    11         public IReadOnlyList<TreeNode<T>> Children { get; set; }
    12 }
    View Code

      为了判等,这个树实现了IEquatable<TreeNode<T>>接口:

     1         public override bool Equals(object obj)
     2         {
     3             var other = obj as TreeNode<T>;
     4             if (other == null)
     5             {
     6                 return false;
     7             }
     8             return Equals(other);
     9         }
    10 
    11         public bool Equals(TreeNode<T> other)
    12         {
    13             return object.Equals(Value, other.Value) && Children.SequenceEqual(other.Children);
    14         }
    15 
    16         public override int GetHashCode()
    17         {
    18             return Value.GetHashCode() ^ Children.Aggregate(Children.Count, (seed, x) => seed ^ x.GetHashCode());
    19         }
    View Code

      看着还不错,不过由于T实际是个复杂类型,每次重写Equals也是个不轻松的事情,而且还要把整个期望的树给构造出来,呵呵,还是烦啊。。。

      但是,如果只需要判定个把简单属性,事情就方便了许多,所以,TreeNode需要一个方法来转换T的类型:

    1         public TreeNode<TResult> Select<TResult>(Func<T, TResult> selector)
    2         {
    3             return new TreeNode<TResult>(selector(Value), (from c in Children select c.Select(selector)).ToList());
    4         }
    View Code

      看起来不错,这样就可以有这样的code来玩转tree了:

    1 TreeNode<int> intTree = ...
    2 TreeNode<string> stringTree = intTree.Select(i => i.ToString());
    View Code

      等等,我们可以把这代码写的跟linq:

    1 TreeNode<int> intTree = ...
    2 TreeNode<string> stringTree = from i in intTree
    3                               select i.ToString();
    View Code

      测试代码继续啪啦啪啦的写,唉,测试失败了,什么情况,仔细一看,哦,tree下面节点的顺序错了,而tree的equals方法要求顺序,但是这个测试刚好不要求顺序,于是我有了两个选择:

    1. 改写equals方法 (不想折腾集合操作)

    2. 让节点排序 (对测试用例而言,构建一个有顺序的树可是很简单的事情)

      所以,我需要个OrderBy:

    1         public TreeNode<T> OrderBy<TKey>(Func<T, TKey> keySelector)
    2         {
    3             return new TreeNode<T>(Value, (from c in Children
    4                                            orderby keySelector(c.Value)
    5                                            select c.OrderBy(keySelector)).ToList());
    6         }
    View Code

      这下就可以随便折腾这个树了:

    1 TreeNode<int> intTree = ...
    2 TreeNode<string> stringTree = from i in intTree
    3                               let m = i % 3
    4                               order by m
    5                               select i.ToString();
    View Code
  • 相关阅读:
    Win10 字体模糊解决(DPI缩放禁用),设置默认输入法英文
    windows下使用VS2015编译V8 JavaScript引擎(v5.5
    GDB 多线程调试:只停止断点的线程,其他线程任然执行; 或只运行某些线程 其他线程中断
    wget 显示"英国中部时间",去掉烦人的刷屏显示
    阻止事件冒泡,阻止默认事件,event.stopPropagation()和event.preventDefault(),return false的区别
    CSS
    bootstrap4 调整元素之间距离
    数据库文件结构、sqlserver ON [PRIMARY]
    快速查看数据库中每个表的数据条数
    关于LINQ中SELECT NEW 的问题
  • 原文地址:https://www.cnblogs.com/vwxyzh/p/4044684.html
Copyright © 2020-2023  润新知