Сегодня утром у меня возникла очень необычная проблема: мне пришлось создать дерево сочетаний клавиш. Это потребовало удобного способа преобразования списка в дерево, и поэтому я придумал следующий класс TreeItem, который работает просто великолепно.
Я решил, что этим стоит поделиться с сообществом, не как модель того, как это следует делать, поскольку такой вещи не существует, а, возможно, чтобы пробудить немного творчества. Конструктивная критика, как всегда, приветствуется!
public class TreeNode : IEnumerable
where T : class
{
public static TreeNode FromList(IEnumerable list, Func keysSelector, Func itemSelector)
{
return new TreeNode(null, GetRootChildren().ToArray());
IEnumerable GetRootChildren()
{
var uniqueKeysList = new List { };
foreach (var listItem in list)
{
var keys = keysSelector(listItem);
var topKey = keys.First();
if (uniqueKeysList.Contains(topKey))
continue;
uniqueKeysList.Add(topKey);
var item = itemSelector(listItem, topKey, 0);
var children = GetChildren(new[] { topKey }, 1).ToArray();
yield return new TreeNode(item, children);
}
}
IEnumerable GetChildren(TKey[] recursionParentKeys, int recursionLevel)
{
foreach (var listItem in list)
{
var keys = keysSelector(listItem);
var bottommostRecursionLevel = keys.Count() - 1;
if (recursionLevel > bottommostRecursionLevel)
continue;
var parentKeys = keys.Take(recursionLevel);
if (recursionParentKeys.SequenceEqual(parentKeys))
yield return CreateChild();
TreeNode CreateChild()
{
var recursionLevelKey = keys.ElementAt(recursionLevel);
var item = itemSelector(listItem, recursionLevelKey, recursionLevel);
return new TreeNode(item, GetChildren(recursionParentKeys.Append(recursionLevelKey).ToArray(), recursionLevel + 1).ToArray());
}
}
}
}
public TreeNode(T item, params TreeNode[] children)
{
Item = item;
this.children = children.ToList();
}
public void AddChild(TreeNode child)
{
children.Add(child);
child.Parent = this;
}
public void RemoveChild(TreeNode child)
{
children.Remove(child);
child.Parent = null;
}
public T Item { get; }
public TreeNode Parent { get; protected set; } = null;
public ReadOnlyCollection Children => children.AsReadOnly();
private List children { get; }
public IEnumerator GetEnumerator() => Children.GetEnumerator();
IEnumerator IEnumerable.GetEnumerator() => Children.GetEnumerator();
}
Вот пример, основанный на моем конкретном сценарии использования:
var chordCommandDictionary = new Dictionary
{
{ new KeysChord { Keys.Control | Keys.A, Keys.Control | Keys.C }, Commands.Command1 },
{ new KeysChord { Keys.Control | Keys.A, Keys.Control | Keys.D }, Commands.Command2 },
{ new KeysChord { Keys.Control | Keys.A, Keys.Control | Keys.E }, Commands.Command3 },
{ new KeysChord { Keys.Control | Keys.B, Keys.Control | Keys.C }, Commands.Command4 },
{ new KeysChord { Keys.Control | Keys.B, Keys.Control | Keys.D }, Commands.Command5 },
{ new KeysChord { Keys.Control | Keys.B, Keys.Control | Keys.E }, Commands.Command6 },
{ new KeysChord { Keys.Control | Keys.B, Keys.Control | Keys.E, Keys.Control | Keys.F }, Commands.Command6 },
};
var tree = TreeNode.FromList(
ChordCommandDictionary,
from => from.Key.Keys,
(from, key, recursionLevel) => new KeysChordStep(key, recursionLevel == from.Key.Keys.Count - 1 ? from.Value : null));
Подробнее здесь: https://stackoverflow.com/questions/792 ... rom-a-list
Класс C# TreeNode, который может конвертировать из списка. ⇐ C#
Место общения программистов C#
-
Anonymous
1731960606
Anonymous
Сегодня утром у меня возникла очень необычная проблема: мне пришлось создать дерево сочетаний клавиш. Это потребовало удобного способа преобразования списка в дерево, и поэтому я придумал следующий класс TreeItem, который работает просто великолепно.
Я решил, что этим стоит поделиться с сообществом, не как модель того, как это следует делать, поскольку такой вещи не существует, а, возможно, чтобы пробудить немного творчества. Конструктивная критика, как всегда, приветствуется!
public class TreeNode : IEnumerable
where T : class
{
public static TreeNode FromList(IEnumerable list, Func keysSelector, Func itemSelector)
{
return new TreeNode(null, GetRootChildren().ToArray());
IEnumerable GetRootChildren()
{
var uniqueKeysList = new List { };
foreach (var listItem in list)
{
var keys = keysSelector(listItem);
var topKey = keys.First();
if (uniqueKeysList.Contains(topKey))
continue;
uniqueKeysList.Add(topKey);
var item = itemSelector(listItem, topKey, 0);
var children = GetChildren(new[] { topKey }, 1).ToArray();
yield return new TreeNode(item, children);
}
}
IEnumerable GetChildren(TKey[] recursionParentKeys, int recursionLevel)
{
foreach (var listItem in list)
{
var keys = keysSelector(listItem);
var bottommostRecursionLevel = keys.Count() - 1;
if (recursionLevel > bottommostRecursionLevel)
continue;
var parentKeys = keys.Take(recursionLevel);
if (recursionParentKeys.SequenceEqual(parentKeys))
yield return CreateChild();
TreeNode CreateChild()
{
var recursionLevelKey = keys.ElementAt(recursionLevel);
var item = itemSelector(listItem, recursionLevelKey, recursionLevel);
return new TreeNode(item, GetChildren(recursionParentKeys.Append(recursionLevelKey).ToArray(), recursionLevel + 1).ToArray());
}
}
}
}
public TreeNode(T item, params TreeNode[] children)
{
Item = item;
this.children = children.ToList();
}
public void AddChild(TreeNode child)
{
children.Add(child);
child.Parent = this;
}
public void RemoveChild(TreeNode child)
{
children.Remove(child);
child.Parent = null;
}
public T Item { get; }
public TreeNode Parent { get; protected set; } = null;
public ReadOnlyCollection Children => children.AsReadOnly();
private List children { get; }
public IEnumerator GetEnumerator() => Children.GetEnumerator();
IEnumerator IEnumerable.GetEnumerator() => Children.GetEnumerator();
}
Вот пример, основанный на моем конкретном сценарии использования:
var chordCommandDictionary = new Dictionary
{
{ new KeysChord { Keys.Control | Keys.A, Keys.Control | Keys.C }, Commands.Command1 },
{ new KeysChord { Keys.Control | Keys.A, Keys.Control | Keys.D }, Commands.Command2 },
{ new KeysChord { Keys.Control | Keys.A, Keys.Control | Keys.E }, Commands.Command3 },
{ new KeysChord { Keys.Control | Keys.B, Keys.Control | Keys.C }, Commands.Command4 },
{ new KeysChord { Keys.Control | Keys.B, Keys.Control | Keys.D }, Commands.Command5 },
{ new KeysChord { Keys.Control | Keys.B, Keys.Control | Keys.E }, Commands.Command6 },
{ new KeysChord { Keys.Control | Keys.B, Keys.Control | Keys.E, Keys.Control | Keys.F }, Commands.Command6 },
};
var tree = TreeNode.FromList(
ChordCommandDictionary,
from => from.Key.Keys,
(from, key, recursionLevel) => new KeysChordStep(key, recursionLevel == from.Key.Keys.Count - 1 ? from.Value : null));
Подробнее здесь: [url]https://stackoverflow.com/questions/79201286/a-c-sharp-treenode-class-that-can-convert-from-a-list[/url]
Ответить
1 сообщение
• Страница 1 из 1
Перейти
- Кемерово-IT
- ↳ Javascript
- ↳ C#
- ↳ JAVA
- ↳ Elasticsearch aggregation
- ↳ Python
- ↳ Php
- ↳ Android
- ↳ Html
- ↳ Jquery
- ↳ C++
- ↳ IOS
- ↳ CSS
- ↳ Excel
- ↳ Linux
- ↳ Apache
- ↳ MySql
- Детский мир
- Для души
- ↳ Музыкальные инструменты даром
- ↳ Печатная продукция даром
- Внешняя красота и здоровье
- ↳ Одежда и обувь для взрослых даром
- ↳ Товары для здоровья
- ↳ Физкультура и спорт
- Техника - даром!
- ↳ Автомобилистам
- ↳ Компьютерная техника
- ↳ Плиты: газовые и электрические
- ↳ Холодильники
- ↳ Стиральные машины
- ↳ Телевизоры
- ↳ Телефоны, смартфоны, плашеты
- ↳ Швейные машинки
- ↳ Прочая электроника и техника
- ↳ Фототехника
- Ремонт и интерьер
- ↳ Стройматериалы, инструмент
- ↳ Мебель и предметы интерьера даром
- ↳ Cантехника
- Другие темы
- ↳ Разное даром
- ↳ Давай меняться!
- ↳ Отдам\возьму за копеечку
- ↳ Работа и подработка в Кемерове
- ↳ Давай с тобой поговорим...
Мобильная версия