[英]Group the items sharing the same parent and child in C#
I wish to find an efficient way to group the items in a tree graph which has the following characteristics: 我希望找到一种在树状图中对项目进行分组的有效方法,它具有以下特征:
About the tree graph, it has multiple layers like this, if drawn horizontally: 关于树图,如果水平绘制,它具有多个这样的层:
(0,0)--(1,0)--(2,0)
\ \-(1,1)--(2,1)
\--(1,2)--/
About "group the items": Because in the data source of the tree there are nodes like: 关于“对项目进行分组”:因为在树的数据源中有类似以下的节点:
(3,5)--(4,10)--(5,5)
\ \-(4,11)-/ /
\ .... /
\--(4,80)--/
I wish to group the nodes like those (4,10~80) above into one node, which these nodes share the same characteristics 我希望将上面的那些节点(4,10〜80)分组为一个节点,这些节点具有相同的特征
using a special class CompoundNode, a subclass of Node. 使用特殊的类CompositeNode,它是Node的子类。
Here is a skeleton class for Node: 这是Node的骨架类:
public class Node
{
public Node(string id)
{
Id = id;
}
public string Id { get; set; }
private readonly List<Node> children = new List<Node>();
public List<Node> Children { get { return children; } }
private readonly List<Node> parents = new List<Node>();
public List<Node> Parents { get { return parents; } }
protected bool Equals(Node other)
{
....
}
public override bool Equals(object obj)
{
....
}
public override int GetHashCode()
{
return (Id != null ? Id.GetHashCode() : 0);
}
public override string ToString()
{
....
}
}
Thanks! 谢谢!
EDIT: 编辑:
Here is the solution i did (extracts the relationship without modifying the tree), without tackling the situation of zero parent or zero child: 这是我所做的解决方案(无需修改树即可提取关系),而无需解决零父零子的情况:
var relationships = new List<Tuple<string, string, string>>();
foreach (var middle in nodes)
{
if (middle.Children.Count == 1 && middle.Parents.Count == 1)
{
var child = middle.Children[0];
var parent = middle.Parents[0];
relationships.Add(new Tuple<string, string, string>(parent.Id, middle.Id, child.Id));
}
}
var groups = relationships.GroupBy(t => new { t.Item1, t.Item3 }).Where(a => a.Count() > 1);
var toGroupedRelations = groups.Cast<IEnumerable<Tuple<string, string, string>>>().ToList();
Ok - here's a first attempt. 好的-这是第一次尝试。 Should give you some good pointers anyway:
无论如何应该给你一些很好的指示:
var nodes = new List<Node>();
// !! populate your nodes list with all your real nodes first!
// filter to nodes with at most 1 parent and 1 child
// group by a tuple containing the parent (if it exists) and the child (if it exists)
var grouped = nodes.Where(i => i.Children.Count <= 1 && i.Parents.Count <= 1)
.GroupBy(i =>
new Tuple<Node, Node>(i.Parents.Count == 0 ? null : i.Parents[0],
i.Children.Count == 0 ? null : i.Children[0]));
// go through your groups - each one should be a cluster of nodes to be merged
foreach (var group in grouped)
{
// get the first node in the group (which one is arbitrary if we're merging anyway)
var node = group.First();
// if this group has a parent
if (node.Parents.Count == 1)
{
// change the parent to only have one child - this one!
node.Parents[0].Children.Clear();
node.Parents[0].Children.Add(node);
}
// if this group has a child
if (node.Children.Count == 1)
{
// change the child to only have one parent - this one!
node.Children[0].Parents.Clear();
node.Children[0].Parents.Add(node);
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.