I have a json string.
There are multiple subcategories within the json string depending on the category. I want to combine them all. It should always give the Id of the last child level of a higher level.
Sample :
Id - Name
-- ----------
1239 - Accessory> Jewelery > wristband> Silver wristband
Can anyone help me . Thanks
{
"categories": [
{
"id": 368,
**"name": "Accessory ",**
"parentId": null,
"subCategories": [
{
"id": 396,
**"name": "Jewelery ",**
"parentId": 368,
"subCategories": [
{
"id": 397,
**"name": "wristband",**
"parentId": 396,
"subCategories": [
{
"id": 1238,
"name": "Gold wristband",
"parentId": 397,
"subCategories": []
},
{
**"id": 1239,**
"name": "Silver wristband",
"parentId": 397,
"subCategories": []
},
{
"id": 2845,
"name": "Steel wristband",
"parentId": 397,
"subCategories": []
},
{
"id": 3171,
"name": "Pearl wristband",
"parentId": 397,
"subCategories": []
},
{
"id": 3883,
"name": "diamond wristband",
"parentId": 397,
"subCategories": []
}
]
}
]
}
]
}
]
}
Here my class
public class SubCategory
{
public int id { get; set; }
public string name { get; set; }
public int parentId { get; set; }
public List<object> subCategories { get; set; }
}
public class Category
{
public int id { get; set; }
public string name { get; set; }
public object parentId { get; set; }
public List<SubCategory> subCategories { get; set; }
}
public class Root
{
public List<Category> categories { get; set; }
}
CodePudding user response:
I think you can drop SubCategory, what is that List<object>
doing there anyway?
Assuming you can deserialize
public class Category
{
public int id { get; set; }
public string name { get; set; }
public int? parentId { get; set; } // int?
public List<Category> subCategories { get; set; } // <Category>
}
public class Root
{
public List<Category> categories { get; set; }
}
then you can use a simple depth-first recursive visitor:
string FindCategoryTrail(List<Category> categories, int id)
{
foreach(var category in categories)
{
if (category.id == id) return category.name;
var trail = FindCategoryTrail(category.subCategories , id);
if (trail != null)
{
return category.name " > " trail;
}
}
return null;
}
and call it like
string trail = FindCategoryTrail(myRoot.categories, 1239);
CodePudding user response:
using Linq, you could flatten the nested lists:
public class Category
{
public int id { get; set; }
public string name { get; set; }
public object parentId { get; set; }
public List<Category> subCategories { get; set; }
}
public class Root
{
public List<Category> categories { get; set; }
}
IEnumerable<Category> Flatten(IEnumerable<Category> e) => e.SelectMany(c => Flatten(c.subCategories)).Concat(e);
Root root = JsonConvert.DeserializeObject<Root>(File.ReadAllText(@"U:\test1.json"));
var search = Flatten(root.categories).Where(c => c.id == 1239);
foreach(var s in search)
{
System.Diagnostics.Debug.WriteLine($"id: {s.id}");
System.Diagnostics.Debug.WriteLine($"name: {s.name}");
System.Diagnostics.Debug.WriteLine($"parentid: {s.parentId}");
}