我有一個自參考的第 n 個深度結構。我想將此結構映射到字串串列中。但我似乎無法成功。
public class SPFolderStructure
{
public string Name { get; set; }
public List<SPFolderStructure> Structure { get; set; }
}
所以結構可以是這樣的:
[
{
"Name": "General",
"Structure": [
{
"Name": "Important",
"Structure": [
{
"Name": "Readings",
"Structure": []
},
{
"Name": "Pictures",
"Structure": []
},
{
"Name": "Support",
"Structure": []
},
{
"Name": "RandomStuff",
"Structure": []
},
{
"Name": "Money",
"Structure": []
},
{
"Name": "Gifs",
"Structure": []
},
{
"Name": "Cells",
"Structure": []
}
]
}
]
},
{
"Name": "Alert",
"Structure": [
{
"Name": "Important",
"Structure": [
{
"Name": "Readings",
"Structure": []
},
{
"Name": "Pictures",
"Structure": []
},
{
"Name": "Support",
"Structure": []
},
{
"Name": "RandomStuff",
"Structure": []
},
{
"Name": "Money",
"Structure": []
},
{
"Name": "Gifs",
"Structure": []
},
{
"Name": "Cells",
"Structure": []
}
]
}
]
}
]
這應該導致 14 個字串
/一般/重要/閱讀
/一般/重要/圖片
/常規/重要/支持
/常規/重要/隨機資料
/一般/重要/金錢
/常規/重要/Gifs
/常規/重要/單元格
/警報/重要/讀數
/警報/重要/圖片
/警報/重要/支持
/警報/重要/RandomStuff
/警報/重要/金錢
/警報/重要/Gifs
/警報/重要/單元格
我嘗試過遞回,并且在簡單的結構上取得了小小的成功,但是對于像這樣的復雜結構,沒有運氣。
public static void DecodeFolderStructure(List<SPFolderStructure> list, List<string> result, string baseName = null, string fullPath = null) {
for (var i = 0; i != list.Count; i ) {
if (string.IsNullOrEmpty(fullPath) && !string.IsNullOrEmpty(baseName)) {
fullPath = $"/{baseName}";
}
var item = list[i];
item.Name = item.Name.Trim();
if (baseName != item.Name) {
fullPath = $"/{item.Name}";
}
if (item.Structure is {Count: > 0}) {
DecodeFolderStructure(item.Structure, result, baseName, fullPath);
fullPath = null;
}
if (fullPath == null) {
continue;
}
result.Add(fullPath);
fullPath = null;
}
}
uj5u.com熱心網友回復:
您的結構很好,而且您創建的類與 JSON 字串完全匹配。您可以簡單地將字串反序列化為物件。接下來,您需要遞回列印出結果,如下所示。
注意:我在您的類中使用了 ToString() 的覆寫作為輸出。您不必這樣做,但在除錯時它也非常方便。
string json = @"[
{
'Name': 'General',
'Structure': [
{
'Name': 'Important',
'Structure': [
{
'Name': 'Readings',
'Structure': []
},
{
'Name': 'Pictures',
'Structure': []
},
{
'Name': 'Support',
'Structure': []
},
{
'Name': 'RandomStuff',
'Structure': []
},
{
'Name': 'Money',
'Structure': []
},
{
'Name': 'Gifs',
'Structure': []
},
{
'Name': 'Cells',
'Structure': []
}
]
}
]
},
{
'Name': 'Alert',
'Structure': [
{
'Name': 'Important',
'Structure': [
{
'Name': 'Readings',
'Structure': []
},
{
'Name': 'Pictures',
'Structure': []
},
{
'Name': 'Support',
'Structure': []
},
{
'Name': 'RandomStuff',
'Structure': []
},
{
'Name': 'Money',
'Structure': []
},
{
'Name': 'Gifs',
'Structure': []
},
{
'Name': 'Cells',
'Structure': []
}
]
}
]
}
]";
// Deserializing the string into a list of SPFolderStructure objects.
List<SPFolderStructure> result = Newtonsoft.Json.JsonConvert.DeserializeObject<List<SPFolderStructure>>(json);
// Now call the recursive routine to print out the result.
DecodeFolderStructure(string.Empty, result);
void DecodeFolderStructure(string parent, List<SPFolderStructure> list)
{
if(list != null)
foreach (SPFolderStructure item in list)
{
var dir = $"{parent}{item}";
Console.WriteLine(dir);
// Recursion here. Call your own routine again.
DecodeFolderStructure(dir, item.Structure);
}
}
Console.ReadKey();
public class SPFolderStructure
{
public string Name { get; set; }
public List<SPFolderStructure> Structure { get; set; }
public override string ToString()
{
return $"/{Name}";
}
}
結果如下:
/General
/General/Important
/General/Important/Readings
/General/Important/Pictures
/General/Important/Support
/General/Important/RandomStuff
/General/Important/Money
/General/Important/Gifs
/General/Important/Cells
/Alert
/Alert/Important
/Alert/Important/Readings
/Alert/Important/Pictures
/Alert/Important/Support
/Alert/Important/RandomStuff
/Alert/Important/Money
/Alert/Important/Gifs
/Alert/Important/Cells
uj5u.com熱心網友回復:
這是一種方法。它利用本地函式來隱藏帶有路徑“累加器”的遞回部分。它只回傳每個串列中葉節點的路徑:
private static IEnumerable<string> DecodeFolderStructure(IEnumerable<SPFolderStructure> structures)
{
return structures.SelectMany(s => GetPaths(s, Enumerable.Empty<string>()));
IEnumerable<string> GetPaths(SPFolderStructure structure, IEnumerable<string> path)
{
path = path.Concat(new[] { structure.Name });
return structure.Structure.Any()
? structure.Structure.SelectMany(s => GetPaths(s, path))
: new[] { string.Join("/", path) };
}
}
請參閱此小提琴以獲取作業演示。
uj5u.com熱心網友回復:
您可以使用帶有遞回的 LINQ 來轉換每個級別:
public static class ListExt {
public static List<string> ToStrings(this List<SPFolderStructure> src)
=> src.SelectMany(s => s.Structure.Count > 0
? s.Structure.ToStrings().Select(s2 => $"/{s.Name}/{s2}")
: new[] { $"/{s.Name}" })
.ToList();
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/455878.html
