Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

210
Visualizações
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 Respostas
Responde à pergunta

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 Relatório

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 Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda