Есть класс. Данные я получаю из Excel файла, пробегаясь по разным листам. Данные есть - теперь надо понять - как построить из них иерархию. Как вообще можно хранить иерархичные данные в списке?
public class DB
{
public string Code { get; set; }
public string Name { get; set; }
public string Id { get; set; }
public string ParentId { get; set; }
}
Допустим есть класс
public class DB
{
public string Code { get; set; }
public string Name { get; set; }
public string Id { get; set; }
public string ParentId { get; set; }
}
Мы можем хранить его в словаре
Dictionary<string, DB> store = new Dictionary<string, DB> ();
Заполним словарь рандомно
var r = new Random();
for(int i=0; i<100; i++)
{
var db = new DB {
Code = $"code {i}",
Id = i.ToString(),
Name = $"name {i}",
ParentId = i % (r.Next(99)+1) == 0 ? null : r.Next(100).ToString()
};
store.Add(db.Id, db);
}
Поиск родителей - тривиальное занятие
public int GetCountOfParents(Dictionary<string, DB> store, string id)
{
var parents = new HashSet<string>();
var q = new Queue<string>();
q.Enqueue(id);
while(q.Count>0)
{
var item = q.Dequeue();
var parent = store[item].ParentId;
if (!string.IsNullOrEmpty(parent) && parents.Add(parent)) q.Enqueue(parent);
}
return parents.Count;
}
Пробежаться по всем элементам еще проще
foreach (var item in store.Values)
Console.WriteLine($"{item.Id} has {GetCountOfParents(store, item.Id)} parents");
Вывод закономерен
0 has 0 parents
1 has 1 parents
2 has 11 parents
3 has 0 parents
4 has 5 parents
5 has 1 parents
.....
91 has 10 parents
92 has 5 parents
93 has 4 parents
94 has 8 parents
95 has 8 parents
96 has 5 parents
97 has 10 parents
98 has 11 parents
99 has 9 parents
Если интересны прямо переходы между парентами, можно добавить вот такую функцию
public IEnumerable<DB> GetParents(Dictionary<string, DB> store, string id)
{
var parents = new HashSet<string>();
var q = new Queue<string>();
q.Enqueue(id);
while (q.Count > 0)
{
var item = q.Dequeue();
var parent = store[item].ParentId;
if (!string.IsNullOrEmpty(parent) && parents.Add(parent))
{
yield return store[parent];
q.Enqueue(parent);
}
}
}
Перечислить все вот так
foreach (var item in store.Values)
Console.WriteLine($"{item.Id} has parents {GetParents(store, item.Id).Aggregate("", (x, y) => $"{x} => {y.Id}")} ");
На выходе получим
0 has parents
1 has parents => 27 => 77 => 19 => 48 => 72 => 2 => 85 => 71 => 59 => 30 => 95 => 58
2 has parents => 85 => 71 => 59 => 30 => 95 => 58
3 has parents => 69 => 54 => 44 => 2 => 85 => 71 => 59 => 30 => 95 => 58
4 has parents => 12 => 39 => 75 => 49 => 14 => 86 => 67 => 61
5 has parents => 57 => 99 => 4 => 12 => 39 => 75 => 49 => 14 => 86 => 67 => 61
6 has parents => 62 => 5 => 57 => 99 => 4 => 12 => 39 => 75 => 49 => 14 => 86 => 67 => 61
7 has parents => 54 => 44 => 2 => 85 => 71 => 59 => 30 => 95 => 58
8 has parents => 13 => 41 => 68 => 37 => 89 => 1 => 27 => 77 => 19 => 48 => 72 => 2 => 85 => 71 => 59 => 30 => 95 => 58
9 has parents => 69 => 54 => 44 => 2 => 85 => 71 => 59 => 30 => 95 => 58
10 has parents => 32 => 6 => 62 => 5 => 57 => 99 => 4 => 12 => 39 => 75 => 49 => 14 => 86 => 67 => 61
11 has parents => 56
.......
91 has parents => 82 => 22 => 85 => 71 => 59 => 30 => 95 => 58
92 has parents => 41 => 68 => 37 => 89 => 1 => 27 => 77 => 19 => 48 => 72 => 2 => 85 => 71 => 59 => 30 => 95 => 58
93 has parents => 84 => 44 => 2 => 85 => 71 => 59 => 30 => 95 => 58
94 has parents
95 has parents => 58
96 has parents => 6 => 62 => 5 => 57 => 99 => 4 => 12 => 39 => 75 => 49 => 14 => 86 => 67 => 61
97 has parents => 43 => 46
98 has parents => 65 => 59 => 30 => 95 => 58
99 has parents => 4 => 12 => 39 => 75 => 49 => 14 => 86 => 67 => 61
Ну и имейте ввиду, что я при генерации совсем не следил за ацикличностью.
UPD
Более простая версия для получения родителей, даже очереди не надо
public IEnumerable<DB> GetParents(Dictionary<string, DB> store, string id)
{
var parents = new HashSet<string>();
id = store[id].ParentId;
while (!string.IsNullOrEmpty(id) && parents.Add(id))
{
yield return store[id];
id = store[id].ParentId;
}
}
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
В общем, есть функция с перегруженным оператором сложенияЕсли степень многочленов одинаковая, то всё считает спокойно, но если степень многочленов...
Например, нужно захешировать пароль методом string CalculateHash(string source)Но если я вытяну значение строки с SecureString в виде экземпляра класса string и передам...
В описаниях DI для asp netcore пишут, что настройка выполняется в ConfigureServices() класса Startup
нужно покрасить определенные столбцы в другой цвет, но проблема в том, что он красит не только столбцы, но и все ячейки до конца файла, как...