I try to group those of file revision which have the same root and make relationship between them
For example:
1.17
1.17.1.1
1.17.1.2
1.17.1.2.1.1
1.17.2.1
1.17.2.2
1.18
1.19
Now I would like to group
1.17, 1.18, 1.19 as the same group and make relationship is parent 1
1.17.1.1, 1.17.1.2 as the same group and make relationship is child 1.1
1.17.2.1, 1.17.2.2 as the same group and make relationship is child 1.2
1.17.1.2.1.1 as the same group and make relationship is grandchild 1.1.1
My idea is loop through the list and try to find number of digit by split by dot then compare it with those of list but it's seem to bad
I don't know is there any best way in VB.NET to achieve it?
The output maybe a datatable, with each data row index revision relationship 1 1.17, 1.18, 1.19 1 2 1.17.1.1, 1.17.1.2 1.1 3 1.17.2.1, 1.17.2.2 1.2 4 1.17.1.2.1.1 1.1.1
The relationship between them 1.17, 1.18, 1.19 (maybe have 1.20, 1.21...) are grouped as a root group 1.17.1.1, 1.17.1.2 (maybe have 1.17.1.3, 1.17.1.4...) are grouped as first child group of root group 1.17.2.1, 1.17.2.2 (maybe have 1.17.2.3, 1.17.2.4...) are grouped as second child group of root group 1.17.1.2.1.1 which have the same path with first child group (1.17.1.1.x.y) are grouped as a first grand child group of first child group
I really appreciate for any help and thanks so much for it.
If you want to create a DataTable from the same list of revisions, then you can achieve that using the same idea with some changes for the grouping/relation issue.
Private Function ToDataTable(revs As IEnumerable(Of String)) As DataTable
Dim dt As New DataTable
dt.Columns.Add("Id", GetType(Integer)).AutoIncrement = True
dt.Columns.Add("ParentId", GetType(Integer))
dt.Columns.Add("Text", GetType(String))
dt.Columns.Add("Path", GetType(String))
dt.Columns.Add("ParentPath", GetType(String))
dt.Columns.Add("Level", GetType(Integer))
For Each rev In revs.OrderBy(Function(x) x)
Dim arr = Regex.Matches(rev, "\d+\.\d+").
Cast(Of Match).Select(Function(x) x.Value).ToArray()
Dim r = dt.NewRow
Dim parentPath = String.Join(".", arr, 0, arr.Count() - 1)
r.SetField("ParentId", dt.Rows.Cast(Of DataRow).
FirstOrDefault(Function(x) x.Field(Of String)("Path") = parentPath)?.
Field(Of Integer)("Id"))
r.SetField("Text", rev)
r.SetField("Path", rev)
r.SetField("ParentPath", parentPath)
r.SetField("Level", arr.Count)
dt.Rows.Add(r)
Next
Return dt
End Function
Also you can create a DataTable from the populated TreeView in the last answer:
Private Iterator Function GetAllNodes(nodes As TreeNodeCollection) _
As IEnumerable(Of TreeNode)
For Each tn In nodes.Cast(Of TreeNode)
Yield tn
For Each cn In GetAllNodes(tn.Nodes)
Yield cn
Next
Next
End Function
Private Function ToDataTable(tv As TreeView) As DataTable
Dim dt As New DataTable
dt.Columns.Add("Id", GetType(Integer)).AutoIncrement = True
dt.Columns.Add("ParentId", GetType(Integer))
dt.Columns.Add("Text", GetType(String))
dt.Columns.Add("Path", GetType(String))
dt.Columns.Add("ParentPath", GetType(String))
dt.Columns.Add("Level", GetType(Integer))
For Each node In GetAllNodes(tv.Nodes)
Dim r = dt.NewRow
Dim parentPath = node.Parent?.Text
r.SetField("ParentId", dt.Rows.Cast(Of DataRow).
FirstOrDefault(Function(x) x.Field(Of String)("Path") = parentPath)?.
Field(Of Integer)("Id"))
r.SetField("Text", node.Text)
r.SetField("Path", node.Text)
r.SetField("ParentPath", parentPath)
r.SetField("Level", node.Level + 1)
dt.Rows.Add(r)
Next
Return dt
End Function
Note here, the node's Level property returns the branch level/group/relation of each node.