-2

I have data in following format

ParentID                            GoalID   GoalName
PId:0#Position:1#Level:1            31       Default Folder
PId:0#Position:2#Level:1            32       Folder 1
PId:0#Position:3#Level:1            33       Folder 2
PId:31#Position:1#Level:2           34       Sub-Folder in Default Folder

Here L1P1 means Level 1 and Position 1.

What I want is I want to sort this on the basis of level and position so the data will look like

ParentID                            GoalID   GoalName
PId:0#Position:1#Level:1            31       Default Folder
PId:31#Position:1#Level:2           34       Sub-Folder in Default Folder
PId:0#Position:2#Level:1            32       Folder 1
PId:0#Position:3#Level:1            33       Folder 2

I have above data in XElement, and apply ordering but can't get desired output.

Ref: I also looked at this but no success

How do I achieve this.

Community
  • 1
  • 1
nrsharma
  • 2,532
  • 3
  • 20
  • 36

2 Answers2

1

This works for me:

var lookup = items.ToLookup(x => x.ParentID);

Func<int, IEnumerable<Goal>> treeOrder = null;
treeOrder = n =>
    lookup[n].SelectMany(x => new [] { x, }.Concat(treeOrder(x.GoalID)));

var results = treeOrder(0);

I get the following output:

Results


The collection items are:

var items = new []
{
    new Goal { TreeID = "L1P1", ParentID = 0, GoalID = 31, GoalName = "Default Folder" },
    new Goal { TreeID = "L1P2", ParentID = 0, GoalID = 32, GoalName = "Folder 1" },
    new Goal { TreeID = "L1P3", ParentID = 0, GoalID = 33, GoalName = "Folder 2" },
    new Goal { TreeID = "L2P1", ParentID = 31, GoalID = 34, GoalName = "Sub-Folder in Default Folder" },
};

Defined with this class:

public class Goal
{
    public string TreeID;
    public int ParentID;
    public int GoalID;
    public string GoalName;
}
Enigmativity
  • 113,464
  • 11
  • 89
  • 172
  • I am not able to understand it. What is items here? And also please see the updated data in the view No TreeId is there level and position is composed in the ParentId. – nrsharma Mar 27 '14 at 07:17
  • @nrsharma - I've removed the `RegEx` answer as it was obviously not correct. My first solution still stands. I've added a definition of `items`. – Enigmativity Mar 27 '14 at 10:31
  • can you make it work with the level & position value from "ParentId"? – nrsharma Mar 27 '14 at 10:34
  • @nrsharma - It does work with the `ParentID` already - unless I'm missing something. – Enigmativity Mar 27 '14 at 12:47
1

Assuming your data is something similar to the following format:

<Tree>
    <TreeID>L1P1</TreeID>
    <ParentID>0</ParentID>
    <GoalID>31</GoalID>
    <GoalName>Default Folder</GoalName>
</Tree>

Basically you want to sort by Position first, then by Level:

var trees = doc.Descendants("Tree")
    .OrderBy(x => Convert.ToInt32(x.Element("TreeID").Value.Substring(x.Element("TreeID").Value.IndexOf("P") + 1)))
    .ThenBy(x => Convert.ToInt32(x.Element("TreeID").Value.Substring(1, x.Element("TreeID").Value.IndexOf("P") - 1)))
    .ToList();
Fung
  • 3,508
  • 2
  • 26
  • 33
  • I did used both OrderBy and ThenBy but it's not giving the correct output. – nrsharma Mar 27 '14 at 07:23
  • @nrsharma I see that you've updated your data format. Do you actually have the Level and Position present in the data? Or it's deduced from the GoalID and whether the record has a ParentID? It's better if you could post the actual XML format of the data. – Fung Mar 28 '14 at 02:04