尼斯和放大器;普遍的方式来转换项目清单,以树尼斯、放大器、清单、普遍

由网友(彩虹糖没有糖)分享简介:我有类别的清单:╔════╦═════════════╦═════════════╗║║编号名称║║PARENT_ID╠════╬═════════════╬═════════════╣║║1体育║║0║║2球║║1║║3║鞋1║║║4║电子0║║║5相机║║4║║6镜头║║5║║7三角架║║5║║...

我有类别的清单:

╔════╦═════════════╦═════════════╗ ║║编号名称║║PARENT_ID ╠════╬═════════════╬═════════════╣ ║║1体育║║0 ║║2球║║1 ║║3║鞋1║ ║║4║电子0║ ║║5相机║║4 ║║6镜头║║5 ║║7三角架║║5 ║║8计算机║║4 ║║9笔记本电脑║║8 ║║10║空0║ ║║-1断║║999 ╚════╩═════════════╩═════════════╝

每个类别有一个父。当父母为0 - 这意味着它的根目录

什么是的最好办法将其转换为树型结构如下图所示?

在换句话说 - 如何从这种结构带来的数据:

类类别 {     公众诠释标识;     公众诠释的ParentId;     公共字符串名称; } 攻城狮不怕天气热就怕电 路 烫 高温系统请注意这些

进入这一个:

类类别 {     公众诠释标识;     公众诠释的ParentId;     公共字符串名称;     公开名单<类别>小类; }

在通用的方式? //通用不仅意味着对上述类。的

你有一些聪明的想法? ;)

数据:

VAR类别=新的名单,其中,类别>(){     新的类别(1,体育,0),     新的类别(2,球,1),     新的类别(3,鞋,1),     新的类别(4,电子,0),     新的类别(5,相机,4),     新的类别(6,镜头,5),     新的类别(7,三足鼎立,5)     新的类别(8,计算机,4),     新的类别(9,笔记本电脑,8),     新的类别(10,空,0),     新的类别(-1,破,999), };

解决方案

如果你想有通用方式you''ll需要一个额外的类:

公共类TreeItem< T> {     公共牛逼项目{获得;组; }     公开的IEnumerable< TreeItem< T>>儿童{获得;组; } }

然后使用这个助手:

 内部静态类GenericHelpers
{
    ///<总结>
    ///生成项目树从项目清单
    ///< /总结>
    ///
    ///< typeparam名=T>在集合&LT项目类型; / typeparam>
    ///< typeparam名=K> PARENT_ID&LT类型; / typeparam>
    ///
    ///< PARAM NAME =收集和GT;收集项< /参数>
    ///< PARAM NAME =id_selector>功能提取产品的ID< /参数>
    ///< PARAM NAME =parent_id_selector>功能提取项目的PARENT_ID< /参数>
    ///< PARAM NAME =root_id>根元素的id< /参数>
    ///
    ///<返回>项&lt树; /回报>
    公共静态的IEnumerable< TreeItem< T>> GenerateTree< T,K>(
        这IEnumerable的< T>采集,
        FUNC< T,K> id_selector,
        FUNC< T,K> parent_id_selector,
        ķroot_id =默认值(K))
    {
        的foreach(VAR c在collection.Where(C => parent_id_selector(三).Equals(root_id)))
        {
            产量返回新TreeItem< T>
            {
                项目= C,
                儿童= collection.GenerateTree(id_selector,parent_id_selector,id_selector(C))
            };
        }
    }
}
 

使用方法:

  VAR根= categories.GenerateTree(C => c.Id,C => c.ParentId);
 

测试:

静态无效测试(IEnumerable的< TreeItem<类别>>类,INT深= 0) {     的foreach(在类变种C)     {         Console.WriteLine(新的字符串( t,深)+ c.Item.Name);         测试(c.Children,深+ 1);     } } // ... 测试(根);

输出

体育     球     鞋 电子     摄像头         镜头         鼎     计算机         笔记本电脑 空洞

I have list of categories:

╔════╦═════════════╦═════════════╗
║ Id ║ Name        ║ Parent_id   ║
╠════╬═════════════╬═════════════╣
║ 1  ║ Sports      ║ 0           ║
║ 2  ║ Balls       ║ 1           ║
║ 3  ║ Shoes       ║ 1           ║
║ 4  ║ Electronics ║ 0           ║
║ 5  ║ Cameras     ║ 4           ║
║ 6  ║ Lenses      ║ 5           ║
║ 7  ║ Tripod      ║ 5           ║
║ 8  ║ Computers   ║ 4           ║
║ 9  ║ Laptops     ║ 8           ║
║ 10 ║ Empty       ║ 0           ║
║ -1 ║ Broken      ║ 999         ║
╚════╩═════════════╩═════════════╝ 

Each category have a parent. When parent is 0 - that means it's the root category.

What is the nicest way to convert it to tree structure like below?

In other words - how to bring data from this structure:

class category
{
    public int Id;
    public int ParentId;
    public string Name;
}

Into this one:

class category
{
    public int Id;
    public int ParentId;
    public string Name;

    public List<Category> Subcategories;
}

in universal way? // Universal means not only for mentioned class.

Do you have some smart ideas? ;)

Data:

var categories = new List<category>() {
    new category(1, "Sport", 0),
    new category(2, "Balls", 1),
    new category(3, "Shoes", 1),
    new category(4, "Electronics", 0),
    new category(5, "Cameras", 4),
    new category(6, "Lenses", 5),  
    new category(7, "Tripod", 5), 
    new category(8, "Computers", 4),
    new category(9, "Laptops", 8),
    new category(10, "Empty", 0),
    new category(-1, "Broken", 999),
};

解决方案

If you want to have universal method you''ll need an additional class:

public class TreeItem<T>
{
    public T Item { get; set; }
    public IEnumerable<TreeItem<T>> Children { get; set; }
}

Then use it with this helper:

internal static class GenericHelpers
{
    /// <summary>
    /// Generates tree of items from item list
    /// </summary>
    /// 
    /// <typeparam name="T">Type of item in collection</typeparam>
    /// <typeparam name="K">Type of parent_id</typeparam>
    /// 
    /// <param name="collection">Collection of items</param>
    /// <param name="id_selector">Function extracting item's id</param>
    /// <param name="parent_id_selector">Function extracting item's parent_id</param>
    /// <param name="root_id">Root element id</param>
    /// 
    /// <returns>Tree of items</returns>
    public static IEnumerable<TreeItem<T>> GenerateTree<T, K>(
        this IEnumerable<T> collection,
        Func<T, K> id_selector,
        Func<T, K> parent_id_selector,
        K root_id = default(K))
    {
        foreach (var c in collection.Where(c => parent_id_selector(c).Equals(root_id)))
        {
            yield return new TreeItem<T>
            {
                Item = c,
                Children = collection.GenerateTree(id_selector, parent_id_selector, id_selector(c))
            };
        }
    }
}

Usage:

var root = categories.GenerateTree(c => c.Id, c => c.ParentId);

Testing:

static void Test(IEnumerable<TreeItem<category>> categories, int deep = 0)
{
    foreach (var c in categories)
    {
        Console.WriteLine(new String('t', deep) + c.Item.Name);
        Test(c.Children, deep + 1);
    }
}
// ...
Test(root);

Output

Sport
    Balls
    Shoes
Electronics
    Cameras
        Lenses  
        Tripod
    Computers
        Laptops
Empty

阅读全文

相关推荐

最新文章