Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

206
Views
Data Set to Tree Structure

I have the below set of data

enter image description here

Where each City belongs to a specific Department, which belongs to a specific Region, which belongs to a specific Country (in this case there is only one country: France).

This data is contained in a CSV file which I can read from on a row-by-row basis, however my goal is to convert this data into a tree structure (with France being at the root).

Each of these nodes will be given a specific Id value, which is something I've already gone and done, but the tricky part is that each node here must also contain a ParentId (for instance Belley and Gex need the ParentId of Ain, but Moulins and Vichy need the ParentId of Aller).

Below is a snippet of code I've written that has assigned an Id value to each name in this data set, along with some other values:

int id = 0;
List<CoverageAreaLevel> coverageAreas = GetCoverageAreaDataFromCsv(path, true);
List<LevelList> levelLists = new List<LevelList>
{
    new LevelList { Names = coverageAreas.Select(a => a.Level1).Distinct().ToList(), Level = "1" },
    new LevelList { Names = coverageAreas.Select(a => a.Level2).Distinct().ToList(), Level = "2" },
    new LevelList { Names = coverageAreas.Select(a => a.Level3).Distinct().ToList(), Level = "3" },
    new LevelList { Names = coverageAreas.Select(a => a.Level4).Distinct().ToList(), Level = "4" }
};
List<CoverageArea> newCoverageAreas = new List<CoverageArea>();
foreach (LevelList levelList in levelLists)
{
    foreach (string name in levelList.Names)
    {
        CoverageArea coverageArea = new CoverageArea
        {
            Id = id++.ToString(),
            Description = name,
            FullDescription = name,
            Level = levelList.Level
        };
        newCoverageAreas.Add(coverageArea);
    }
}

The levelLists variable contains a sort-of heirarchical structure of the data that I'm looking for, but none of the items in that list are linked together by anything.

Any idea of how this could be implemented? I can manually figure out each ParentId, but I'd like to automate this process, especially if this needs to be done in the future.

over 4 years ago · Santiago Trujillo
2 answers
Answer question

0

The solution from @Camilo is really good and pragmatic. I would also suggest the use of a tree.

A sample implementation:

var countries = models.GroupBy(xco => xco.Country)
        .Select((xco, index) =>
        {
            var country = new Tree<String>();
            country.Value = xco.Key;
            country.Children = xco.GroupBy(xr => xr.Region)
                    .Select((xr, xrIndex) =>
                    {
                        var region = new Tree<String>();
                        region.Value = xr.Key;
                        region.Parent = country;
                        region.Children =
                                xr.GroupBy(xd => xd.Department)
                                    .Select((xd, index) =>
                                    {
                                        var department = new Tree<String>();
                                        department.Value = xd.Key;
                                        department.Parent = region;
                                        department.Children = xd
                                        .Select(xc => new Tree<String> { Value = xc.City, Parent = department });
                                        return department;
                                    });

                        return region;
                    });
            return country;
        });

public class Tree<T>
{
    public IEnumerable<Tree<T>> Children;
    public T Value;
    public Tree<T> Parent;
}
over 4 years ago · Santiago Trujillo Report

0

One way you could solve this is by building dictionaries with the names and IDs of each level.

Assuming you have data like this:

var models = new List<Model> 
{
    new Model { Country = "France", Region = "FranceRegionA", Department = "FranceDept1", City = "FranceA" },
    new Model { Country = "France", Region = "FranceRegionA", Department = "FranceDept1", City = "FranceB" },
    new Model { Country = "France", Region = "FranceRegionA", Department = "FranceDept2", City = "FranceC" },
    new Model { Country = "France", Region = "FranceRegionB", Department = "FranceDept3", City = "FranceD" },
    new Model { Country = "Italy", Region = "ItalyRegionA", Department = "ItalyDept1", City = "ItalyA" },
    new Model { Country = "Italy", Region = "ItalyRegionA", Department = "ItalyDept2", City = "ItalyB" },
};

You could do something like this, which can probably be improved further if needed:

var countries = models.GroupBy(x => x.Country)
    .Select((x, index) => Tuple.Create(x.Key, new { Id = index + 1 }))
    .ToDictionary(x => x.Item1, x => x.Item2);

var regions = models.GroupBy(x => x.Region)
    .Select((x, index) => Tuple.Create(x.Key, new { ParentId = countries[x.First().Country].Id, Id = index + 1 }))
    .ToDictionary(x => x.Item1, x => x.Item2);

var departments = models.GroupBy(x => x.Department)
    .Select((x, index) => Tuple.Create(x.Key, new { ParentId = regions[x.First().Region].Id, Id = index + 1 }))
    .ToDictionary(x => x.Item1, x => x.Item2);

var cities = models
    .Select((x, index) => Tuple.Create(x.City, new { ParentId = departments[x.Department].Id, Id = index + 1 }))
    .ToDictionary(x => x.Item1, x => x.Item2);

The main idea is to leverage the index parameter of the Select method and the speed of dictionaries to find the parent ID.

Sample output from a fiddle:

countries:
   [France, { Id = 1 }],
   [Italy, { Id = 2 }]

regions:
   [FranceRegionA, { ParentId = 1, Id = 1 }],
   [FranceRegionB, { ParentId = 1, Id = 2 }],
   [ItalyRegionA, { ParentId = 2, Id = 3 }]

departments:
   [FranceDept1, { ParentId = 1, Id = 1 }],
   [FranceDept2, { ParentId = 1, Id = 2 }],
   [FranceDept3, { ParentId = 2, Id = 3 }],
   [ItalyDept1, { ParentId = 3, Id = 4 }],
   [ItalyDept2, { ParentId = 3, Id = 5 }]

cities:
   [FranceA, { ParentId = 1, Id = 1 }],
   [FranceB, { ParentId = 1, Id = 2 }],
   [FranceC, { ParentId = 2, Id = 3 }],
   [FranceD, { ParentId = 3, Id = 4 }],
   [ItalyA, { ParentId = 4, Id = 5 }],
   [ItalyB, { ParentId = 5, Id = 6 }]
over 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!