zoukankan      html  css  js  c++  java
  • 获取多级类别组合下的产品

    本篇是针对我在做项目过程中遇到的特定需求而做的一个Demo, 没有很大的通用性,读者酌情可绕行。

     

    标题不能完全表达本意,确切的情景需要展开说。假设有三级分类,关于分类这样设计:

     

        public class Category
    
        {
    
            public int Id { get; set; }
    
            public string Name { get; set; }
    
            public int ParentId { get; set; }
    
        }

     

    然后产品可以属于多个分类,以下的Categories属性值是以英文逗号隔开、由分类编号拼接而成的字符串。

     

        public class Product
    
        {
    
            public int Id { get; set; }
    
            public string Name { get; set; }
    
            public string Categories { get; set; }
    
        }

     

    由于种种原因,Categories属性值只是存储了由第三级分类编号拼接而成的字符串。

     

    在前端,需要把分类作为查询条件来查询产品,可能只选择一级分类,把一个数字字符串(比如"1")发送给服务端;可能同时选择一级和二级分类,也把一个数字字符串(比如"1,2")发送给服务端;当然,也有可能同时选择一级、二级和三级分类作为查询条件(比如"1,2,3")。换句话说,如果诸如"1"或"1,2"或"1,2,3"这样的查询条件转换成数组后,如果数组的每一个元素都被包含在Product的Categories属性值转换成的数组中,那这个产品就符合搜索条件。

     

    简单来说,是这样:假设搜索条件是"1,2",Product的Categories属性值为"1,3,2,5",我们不是判断"1,2"这个字符串是否包含在"1,3,2,5"字符串中,而是把"1,2"先split成数组,叫做array1, 把"1,3,2,5"也split成数组,叫做array2,最后判断array1的每个元素是否都被包含在array2中。

     

    还有一个问题需要解决:当前的Product的Categories属性值只存储了所有第三级分类编号拼接成的字符串,而前端输入的搜索条件可能会包含一级分类或二级分类等,所以,我们需要把Product转换一下,希望有一个类的某个属性值能存储由一级、二级、三级分类拼接而成的字符串。

     

        public class ProductWithThreeCate
    
        {
    
            public int Id { get; set; }
    
            public string Name { get; set; }
    
            public string AllCategoreis { get; set; }
    
        }

     

    以上, AllCategoreis属性值就用来存储由一级、二级、三级分类拼接而成的字符串。

     

    有一个方法获取所有分类:

            static List<Category> GetCategories()
    
            {
    
                return new List<Category>()
    
                {
    
                    new Category(){Id = 1, Name = "", ParentId = -1},
    
                    new Category(){Id = 2, Name = "一级分类1",ParentId = 1},
    
                    new Category(){Id = 3, Name = "一级分类2", ParentId = 1},
    
                    new Category(){Id = 4, Name = "二级分类11",ParentId = 2},
    
                    new Category(){Id = 5, Name = "二级分类12",ParentId = 2},
    
                    new Category(){Id = 6, Name = "二级分类21",ParentId = 3},
    
                    new Category(){Id = 7, Name = "二级分类22",ParentId = 3},
    
                    new Category(){Id = 8, Name = "三级分类111",ParentId = 4},
    
                    new Category(){Id = 9, Name = "三级分类112",ParentId = 4},
    
                    new Category(){Id = 10, Name = "三级分类121",ParentId = 5},
    
                    new Category(){Id = 11, Name = "三级分类122",ParentId = 5},
    
                    new Category(){Id = 12, Name = "三级分类211",ParentId = 6},
    
                    new Category(){Id = 13, Name = "三级分类212",ParentId = 6},
    
                    new Category(){Id = 14, Name = "三级分类221",ParentId = 7}
    
                };
    
            }

    有一个方法获取所有产品:

            static List<Product> GetProducts()
    
            {
    
                return new List<Product>()
    
                {
    
                    new Product(){Id = 1, Name = "产品1",Categories = "10,12"},
    
                    new Product(){Id = 2, Name = "产品2", Categories = "12,13"},
    
                    new Product(){Id = 3, Name = "产品3",Categories = "10,11,12"},
    
                    new Product(){Id = 4, Name = "产品4",Categories = "13,14"},
    
                    new Product(){Id = 5, Name = "产品5",Categories = "11,13,14"}
    
                };
    
            }    

    接下来的方法是根据搜索条件(比如是"1,2")来查找满足条件的ProductWithThreeCate集合,如下:

     

            /// <summary>
    
            /// 获取满足某些条件的集合
    
            /// </summary>
    
            /// <param name="query">以英文逗号隔开的字符串,比如:2,5</param>
    
            /// <returns></returns>
    
            static List<ProductWithThreeCate> GetResultByQuery(string query)
    
            {
    
                //最终结果
    
                List<ProductWithThreeCate> result = new List<ProductWithThreeCate>();
    
                //临时结果 此时ProductWithThreeCat的属性AllCategoreis包含所有一级、二级、三级分类ID拼接成的字符串
    
                List<ProductWithThreeCate> tempResult = new List<ProductWithThreeCate>();
    
                //获取所有的产品
    
                List<Product> allProducts = GetProducts();
    
                //遍历这些产品
    
                foreach (var item in allProducts)
    
                {
    
                    ProductWithThreeCate productWithThreeCate = new ProductWithThreeCate();
    
                    productWithThreeCate.Id = item.Id;
    
                    productWithThreeCate.Name = item.Name;
    
                    //所有一级、二级、三级拼接成以英文逗号隔开的字符串
    
                    string temp = string.Empty;
    
                    //当前产品只包含三级拼接成的、也是以英文隔开的字符串,split成数组
    
                    string[] theThirdCates = item.Categories.Split(',');
    
                    //遍历这些三级数组
    
                    foreach (string i in theThirdCates)
    
                    {
    
                        //三级类别转换成整型
    
                        int theThirdInt = int.Parse(i);
    
                        //获取三级类别
    
                        Category theThirdCate = GetCategories().Where(c => c.Id == theThirdInt).FirstOrDefault();
    
                        //获取二级类别
    
                        Category theSecondCate = GetCategories().Where(c => c.Id == theThirdCate.ParentId).FirstOrDefault();
    
                        //获取一级类别
    
                        Category theFirstCate = GetCategories().Where(c => c.Id == theSecondCate.ParentId).FirstOrDefault();
    
                        temp += i + "," + theSecondCate.Id.ToString() + "," + theFirstCate.Id.ToString() + ",";
    
                    }
    
                    //去掉最后一个英文逗号
    
                    temp = temp.Substring(0, temp.Length - 1);
    
                    //转换成集合,去除重复项,比如不同的三级可能有相同的一级或二级父类
    
                    IEnumerable<string> tempArray = temp.Split(',').AsEnumerable().Distinct();
    
                    //所有一级、二级、三级拼接成以英文逗号隔开的字符串,但已经去除了重复的一级和二级
    
                    string tempagain = string.Empty;
    
                    //再次遍历集合拼接成字符串
    
                    foreach (var s in tempArray)
    
                    {
    
                        tempagain += s + ",";
    
                    }
    
                    productWithThreeCate.AllCategoreis = tempagain.Substring(0, tempagain.Length - 1);
    
                    tempResult.Add(productWithThreeCate);
    
                }
    
                //遍历临时结果
    
                foreach (var item in tempResult)
    
                {
    
                    //把当前包含一级、二级、三级的,以英文逗号隔开的字符串split成数组
    
                    string[] itemArray = item.AllCategoreis.Split(',');
    
                    //把当前查询字符串split成数组
    
                    string[] queryArray = query.Split(',');
    
                    //如果queryArray的每一个元素都被包含在itemArray中,那就保存起来
    
                    if (queryArray.All(x => itemArray.Contains(x)) == true)
    
                    {
    
                        result.Add(item);
    
                    }
    
                }
    
                return result;
    
            }                
    

     

    客户端的调用如下:

     

                List<ProductWithThreeCate> result = GetResultByQuery("2,5");
    
                //遍历最终的结果
    
                foreach (var item in result)
    
                {
    
                    Console.WriteLine(item.Name+ "  " + item.AllCategoreis);
    
                }
    
                Console.ReadKey(); 
    

                 

  • 相关阅读:
    【LeetCode】17. Letter Combinations of a Phone Number
    【LeetCode】16. 3Sum Closest
    【LeetCode】15. 3Sum 三个数和为0
    【LeetCode】14. Longest Common Prefix 最长前缀子串
    【LeetCode】13. Roman to Integer 罗马数字转整数
    【LeetCode】12. Integer to Roman 整型数转罗马数
    【LeetCode】11. Container With Most Water
    【LeetCode】10. Regular Expression Matching
    Models of good programmer
    RSA Algorithm
  • 原文地址:https://www.cnblogs.com/darrenji/p/4267926.html
Copyright © 2011-2022 走看看