2017-01-18 9 views
-1

ID(機能場所)、説明&親ID(SupFunctLoc)のすべてが文字列である.csvファイルから階層を構築しようとしています。私はリストにデータを取り込んだ。 コード&参照用データサンプル。再帰親子関係C#

Functional Loc. Description SupFunctLoc. 
70003 ABC AS002 
70C2 ABC 70003 
70C2.01 ABC 70C2 
70C2.01.02 ABC 70C2.01 
70C2.01.02.10 ABC 70C2.01.02 
70C2.01.02.10-BG010 ABC 70C2.01.02.10 

サンプルコード:

static void Main(string[] args) 
    { 
     List<Input> inputList = new List<Input>(); 
     var yourData = File.ReadAllLines(locate) 
       .Skip(1) 
       .Select(x => x.Split(',')) 
       .Select(x => new Input() 
       { 
        FunctionalLocation = x[0], 
        Description = x[1], 
        SuppFunctionalLocation = x[2], 

       }); 
     //try 3 

     //try 2 

     var outputList = yourData 
      .Where(i => i.SuppFunctionalLocation!= null) // Just get the parents 
      .Select(i => new Input() 
      { 
       Description = i.Description, 
       SuppFunctionalLocation = i.SuppFunctionalLocation, 
       Children = inputList 
        .Where(x => x.FunctionalLocation.ToString() == i.SuppFunctionalLocation.ToString()) 
        .Select(x => new Input() 
        { 
         Description = x.Description, 
         SuppFunctionalLocation = x.SuppFunctionalLocation, 
         FunctionalLocation = x.FunctionalLocation, 
        }).ToList() 
       }).ToList(); 


     foreach (var output in outputList) 
     { 
      Console.WriteLine(output.Description); 
      output.Children.ForEach(c => Console.WriteLine($"\t {c.Description}")); 
     } 
} 

クラスDefination入力

class Input 
    { 
     public string FunctionalLocation { get; set; } 
     public string Description { get; set; } 
     public string SuppFunctionalLocation { get; set; } 
     public List<Input> Children { get; set; } 
    } 

ため、この場合に何ができるか助けてください。あなたの助けに感謝します。

+3

あなたは '、'で分割していますが、サンプルテキストにカンマはありません。また、 'Input'のためのクラスdefを提供する必要があります。 – Enigmativity

+0

@Enigmativityこんにちは私はデータのサンプルを貼り付け、クラス入力定義で質問を更新しました – user5928466

+0

'Functional Loc.'は主キーですか? – nozzleman

答えて

0

これを試してみてください:

var source = @"Functional Loc. Description SupFunctLoc. 
70003 ABC AS002 
70C2 ABC 70003 
70C2.01 ABC 70C2 
70C2.01.02 ABC 70C2.01 
70C2.01.02.10 ABC 70C2.01.02 
70C2.01.02.10-BG010 ABC 70C2.01.02.10"; 

var lines = 
    source 
     .Split(Environment.NewLine.ToCharArray(), StringSplitOptions.RemoveEmptyEntries) 
     .Select(x => x.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries)); 

var results = 
    lines 
     .Skip(1) 
     .Select(x => new Input() 
     { 
      FunctionalLocation = x[0], 
      Description = x[1], 
      SuppFunctionalLocation = x[2], 
     }); 

var lookup = results.ToLookup(x => x.SuppFunctionalLocation); 

Func<string, List<Input>> build = null; 
build = SuppFunctionalLocation => 
    lookup[SuppFunctionalLocation] 
     .Select(x => new Input() 
     { 
      FunctionalLocation = x.FunctionalLocation, 
      Description = x.Description, 
      SuppFunctionalLocation = x.SuppFunctionalLocation, 
      Children = build(x.FunctionalLocation), 
     }) 
     .ToList(); 

List<Input> tree = build("AS002"); 
+0

ありがとうございました:) – user5928466

0

既存の親キーを持つアイテムから階層を構築するのは比較的簡単です。私はあなたのサンプルからそれを少し抽象化しましたが、基本的に同じです。

階層に置くべき項目

public class MyItem 
{ 
    public string Id { get; set; } 
    public string Description { get; set; } 
    public string ParentId { get; set; } 
    // to be filled 
    public IList<MyItem> Children { get; set; } 
} 

子リストを構築するためのコード。

// assumption: MyItem elements have all properties set except the children collection 
ICollection<MyItem> items = GetMyItems(); 

var parentRelation = items.ToLookup(x => x.ParentId); 
foreach (var item in items) 
{ 
    item.Children = parentRelation[item.Id].ToList(); 
} 
+0

ありがとうたくさん... :) – user5928466

1

あなたはすべてのために見ているだけのルート要素を取得するには

foreach (var parent in inputlist) 
{ 
    parent.Children = inputlist 
     .Where(child => child.SuppFunctionalLocation == parent.FunctionalLocation) 
     .ToList(); 
} 

との親子関係を築くコレクションにすべての項目を読んでたら親を持たないアイテム