I have a list of categories with duplicate key values AppCategoryId
. I wanted to create a 3 level hierarchy with that.
Data are in this way:
var appCategoryList = new List<AppCategoryDataModel>() {
new AppCategoryDataModel() { AppCategoryId = 4844, ParentappCategoryId = null , AppCategoryName = "ItemResearch", ProtocolId = 5164, ProtocolTitle="ABC: Evaluation" },
new AppCategoryDataModel() { AppCategoryId = 4844, ParentappCategoryId = null, AppCategoryName = "ItemResearch", ProtocolId = null, ProtocolTitle=""},
new AppCategoryDataModel() { AppCategoryId = 4845, ParentappCategoryId = null, AppCategoryName = "ItemHostpital", ProtocolId = null, ProtocolTitle="" },
new AppCategoryDataModel() { AppCategoryId = 4845, ParentappCategoryId = null, AppCategoryName = "ItemHostpital", ProtocolId =5162 , ProtocolTitle="ABC: 3/28/20" },
new AppCategoryDataModel() { AppCategoryId = 4845, ParentappCategoryId = null, AppCategoryName = "ItemHostpital", ProtocolId =5164 , ProtocolTitle="ABC: Evaluation" },
new AppCategoryDataModel() { AppCategoryId = 4845, ParentappCategoryId = null, AppCategoryName = "ItemHostpital", ProtocolId =5165 , ProtocolTitle="ABC: section", },
new AppCategoryDataModel() { AppCategoryId = 4845, ParentappCategoryId = null, AppCategoryName = "ItemHostpital", ProtocolId =5192 , ProtocolTitle="ABC: 3/31/20", },
new AppCategoryDataModel() { AppCategoryId = 4846, ParentappCategoryId = null, AppCategoryName = "Contact information", ProtocolId = null, ProtocolTitle="", },
new AppCategoryDataModel() { AppCategoryId = 4846, ParentappCategoryId = null, AppCategoryName = "Contact information", ProtocolId =5164 , ProtocolTitle="ABC: Evaluation", },
new AppCategoryDataModel() { AppCategoryId = 4852, ParentappCategoryId = null, AppCategoryName = "UP", ProtocolId =null , ProtocolTitle="", },
new AppCategoryDataModel() { AppCategoryId = 4852, ParentappCategoryId = null, AppCategoryName = "UP", ProtocolId = 5164, ProtocolTitle="ABC: Evaluation", },
new AppCategoryDataModel() { AppCategoryId = 4853, ParentappCategoryId = null, AppCategoryName = "Hospitalist", ProtocolId = null, ProtocolTitle="", },
new AppCategoryDataModel() { AppCategoryId = 4853, ParentappCategoryId = null, AppCategoryName = "Hospitalist", ProtocolId = 5164, ProtocolTitle="ABC: Evaluation" },
new AppCategoryDataModel() { AppCategoryId = 4854, ParentappCategoryId = null, AppCategoryName = "COP", ProtocolId =null , ProtocolTitle=""},
new AppCategoryDataModel() { AppCategoryId = 4854, ParentappCategoryId = null, AppCategoryName = "COP", ProtocolId = 5162, ProtocolTitle="ABC: 3/28/20"},
new AppCategoryDataModel() { AppCategoryId = 4854, ParentappCategoryId = null, AppCategoryName = "COP", ProtocolId = 5164, ProtocolTitle="ABC: Evaluation" },
new AppCategoryDataModel() { AppCategoryId = 5023, ParentappCategoryId = null, AppCategoryName = "Call survival guide", ProtocolId = null, ProtocolTitle="" },
new AppCategoryDataModel() { AppCategoryId = 5023, ParentappCategoryId = null, AppCategoryName = "Call survival guides", ProtocolId =5164 , ProtocolTitle="ABC: Evaluation" },
new AppCategoryDataModel() { AppCategoryId = 5085, ParentappCategoryId = null, AppCategoryName = "OE", ProtocolId =null, ProtocolTitle="" },
new AppCategoryDataModel() { AppCategoryId = 5085, ParentappCategoryId = null, AppCategoryName = "OE", ProtocolId =5164 , ProtocolTitle="ABC: Evaluation" },
new AppCategoryDataModel() { AppCategoryId = 5334, ParentappCategoryId = 5085, AppCategoryName = "mmkk update", ProtocolId =null , ProtocolTitle= null },
new AppCategoryDataModel() { AppCategoryId = 5336, ParentappCategoryId = 5085, AppCategoryName = "xdgdrg", ProtocolId =null , ProtocolTitle=null },
new AppCategoryDataModel() { AppCategoryId = 5348, ParentappCategoryId = 5023, AppCategoryName = "test", ProtocolId =null , ProtocolTitle=null },
new AppCategoryDataModel() { AppCategoryId = 5341, ParentappCategoryId = 5023, AppCategoryName = "New Category Level-1", ProtocolId =null , ProtocolTitle= null },
new AppCategoryDataModel() { AppCategoryId = 5349, ParentappCategoryId = 5341, AppCategoryName = "New Category Level-2", ProtocolId =null , ProtocolTitle= null },
new AppCategoryDataModel() { AppCategoryId = 5352, ParentappCategoryId = 5348, AppCategoryName = "New category3", ProtocolId =null , ProtocolTitle= null },
}.OrderBy(ap => ap.AppCategoryName);
AppCategoryDataModel
public class AppCategoryDataModel
{
public int AppCategoryId { get; set; }
public int? ParentappCategoryId { get; set; }
public string AppCategoryName { get; set; }
public int? ProtocolId { get; set; }
public string ProtocolTitle { get; set; }
}
Converted the list to lookup:
var lookup = appCategoryList.ToLookup(app => app.AppCategoryId);
Iterated through the list:
var listofCategory = new List<FirstLevelCategory>();
foreach (var item in appCategoryList)
{
var firstLevelCategory = new FirstLevelCategory();
if (!item.ParentappCategoryId.HasValue)
{
firstLevelCategory.AppCategoryId = item.AppCategoryId;
firstLevelCategory.AppCategoryName = item.AppCategoryName;
firstLevelCategory.AppCategoryProtocolData = new List<ProtocolDetails>();
var protocolDetails = new ProtocolDetails();
foreach (AppCategoryDataModel appCategory in lookup[item.AppCategoryId])
{
if (appCategory.ProtocolId.HasValue)
{
protocolDetails.ProtocolId = appCategory.ProtocolId.Value;
protocolDetails.ProtocolTitle = appCategory.ProtocolTitle;
}
firstLevelCategory.AppCategoryProtocolData.Add(protocolDetails);
}
continue;
}
else
{
}
listofCategory.Add(firstLevelCategory);
}
In the foreach when 'appCategoryList' is iterated first it works fine. But in the next loop due to the repetition of the same appcategoryid there will be a duplicate addition of the same data as much as time the appcateogory id is present.
After all the data has been added I could remove them at the end but it will be another task, what could be done to avoid the addition of the duplicate first?
Alternatively, I tried this way But in this way, only the last item will be added to the list.
foreach (var item in lookup)
{
var firstLevelCategory = new FirstLevelCategory();
List<AppCategoryDataModel> categoryList = item.ToList(); foreach (var item in lookup)
{
var firstLevelCategory = new FirstLevelCategory();
List<AppCategoryDataModel> categoryList = item.ToList();
foreach (AppCategoryDataModel appCategory in categoryList)
{
if (!appCategory.ParentappCategoryId.HasValue)
{
firstLevelCategory.AppCategoryId = appCategory.AppCategoryId;
firstLevelCategory.AppCategoryName = appCategory.AppCategoryName;
firstLevelCategory.AppCategoryProtocolData = new List<ProtocolDetails>();
var protocolDetails = new ProtocolDetails();
if (appCategory.ProtocolId.HasValue)
{
protocolDetails.ProtocolId = appCategory.ProtocolId.Value;
protocolDetails.ProtocolTitle = appCategory.ProtocolTitle;
}
firstLevelCategory.AppCategoryProtocolData.Add(protocolDetails);
}
else
{
}
}
listofCategory.Add(firstLevelCategory);
}
I how can I add the item to the list effectively with a much cheaper approach?
public class FirstLevelCategory
{
public int AppCategoryId { get; set; }
public string AppCategoryName { get; set; }
public List<SecondLevelCategory> SubCategory { get; set; }
public List<ProtocolDetails> AppCategoryProtocolData { get; set; }
}
public class ProtocolDetails
{
public int ProtocolId { get; set; }
public string ProtocolTitle { get; set; }
}
SecondLevelCategory
public class SecondLevelCategory
{
public int AppCategoryId { get; set; }
public string AppCategoryName { get; set; }
public IEnumerable<ProtocolDetails> SubCategoryProtocolData { get; set; }
public List<ThirdLevelCategory> ThirdLevelCategory { get; set; }
}
ThirdLevelCategory
public class ThirdLevelCategory
{
public int AppCategoryId { get; set; }
public string AppCategoryName { get; set; }
public IEnumerable<ProtocolDetails> ThirdLevelCategoryProtocolData { get; set; }
}
Expected Output are something similar (output for the first category only)
ItemResearch
ABC: Evaluation
ItemHostpital
ABC: 3/28/20
ABC: Evaluation
ABC: section
ABC: 3/31/20
Contact information
ABC: Evaluation
UP
ABC: Evaluation
Edit: More data are added that have parentscategoryid, and class for first, second and third level are added.
CodePudding user response:
Using dictionaries makes your life easier:
Dictionary<int, FirstLevelCategory> dictCategories = new Dictionary<int, FirstLevelCategory>();
foreach (AppCategoryDataModel category in appCategoryList)
{
if (!dictCategories.ContainsKey(category.AppCategoryId))
{
dictCategories.Add(category.AppCategoryId, new FirstLevelCategory()
{
AppCategoryId = category.AppCategoryId,
AppCategoryName = category.AppCategoryName,
AppCategoryProtocolData = category.ProtocolId != null ? new List<ProtocolDetails>() { new ProtocolDetails() {
ProtocolId = (int)category.ProtocolId,
ProtocolTitle = category.ProtocolTitle
} } : new List<ProtocolDetails>()
});
}
else
{
if (category.ProtocolId != null)
dictCategories[category.AppCategoryId].AppCategoryProtocolData.Add(new ProtocolDetails()
{
ProtocolId = (int)category.ProtocolId,
ProtocolTitle = category.ProtocolTitle
});
}
}
var test = dictCategories.Values.ToList();
I didn't check for duplicates in protocol, as for yours code seems there is no need but if it's needed you can do it the same way