集合(6-Lookup)

Lookup的概念

Lookup 类似于 Dictionary,但把键映射到一个值集上 (通俗讲法就是一个键对应多个值)
这个类在程序集System.Core中实现,用System.Linq命名空间定义。
它不能像一般的字典那样创建,而必须调用方法ToLookup()。
Lookup和IGrouping有点类似但又有点区别。

示例

参考示例

首先建一个产品类:有ID、类别、价格

internal class Product
    {
        public int id { get; set; }
        public string category { get; set; }
        public double value { get; set; }
        public override string ToString()
        {
            return string.Format("[{0}: {1} - {2}]", id, category, value);
        }
    }

接着定义一个获得产品集的方法,当然,你也可以查询数据库来获取数据

public static List<Product> GetList()
        {
            var products = new List<Product>
                               {
                                   new Product {id = 1, category = "Electronics", value = 15.0},
                                   new Product {id = 2, category = "Groceries", value = 40.0},
                                   new Product {id = 3, category = "Garden", value = 210.3},
                                   new Product {id = 4, category = "Pets", value = 2.1},
                                   new Product {id = 5, category = "Electronics", value = 19.95},
                                   new Product {id = 6, category = "Pets", value = 21.25},
                                   new Product {id = 7, category = "Pets", value = 5.50},
                                   new Product {id = 8, category = "Garden", value = 13.0},
                                   new Product {id = 9, category = "Automotive", value = 10.0},
                                   new Product {id = 10, category = "Electronics", value = 250.0},
                               };
            return products;
        }

先使用List的GroupBy方法根据产品类别对产品进行分组

static void Main(string[] args)
        {
            IList<Product> products = GetList();


            IEnumerable<IGrouping<string, Product>> groups = products.GroupBy(a => a.category);
            foreach (IGrouping<string, Product> group in groups)
            {
                Console.WriteLine(group.Key);
                foreach (Product product in group)
                {
                    Console.WriteLine(product);
                }
            }
            //Electronics
            //[1: Electronics - 15]
            //[5: Electronics - 19.95]
            //[10: Electronics - 250]
            //Groceries
            //[2: Groceries - 40]
            //Garden
            //[3: Garden - 210.3]
            //[8: Garden - 13]
            //Pets
            //[4: Pets - 2.1]
            //[6: Pets - 21.25]
            //[7: Pets - 5.5]
            //Automotive
            //[9: Automotive - 10]
        }

看起来一切都很好,没有什么问题.
  当我们使用 GroupBy() 扩展方法时,使用了延迟执行。 这意味着,当你遍历集合的时候,下一个要出现的项目可能会或者可能不会被加载。 这是一个很大的性能改进,但它会引起有趣的副作用。
  在用 GroupBy()时, 它实际上是在第一项被使用的时候创建分组,而不是在 GroupBy() 第一次被调用时。

 static void Main(string[] args)
        {
            List<Product> products = GetList();


            IEnumerable<IGrouping<string, Product>> groups = products.GroupBy(a => a.category);
            //移除类别为Garden的产品
            products.RemoveAll(a => a.category == "Garden");

            foreach (IGrouping<string, Product> group in groups)
            {
                Console.WriteLine(group.Key);
                foreach (Product product in group)
                {
                    Console.WriteLine(product);
                }
            }
            //Electronics
            //[1: Electronics - 15]
            //[5: Electronics - 19.95]
            //[10: Electronics - 250]
            //Groceries
            //[2: Groceries - 40]
            //Pets
            //[4: Pets - 2.1]
            //[6: Pets - 21.25]
            //[7: Pets - 5.5]
            //Automotive
            //[9: Automotive - 10]
        }

执行后发现,所有的Garden产品都已经消失了,但是 groups 是在执行删除命令前就已经赋值了。

基于这种情况,我们不得不使用ToDictionary() 将GroupBy 后的结果储存起来,这样一来工作量就增加了,而且维护也不太方便 – 请大家试试。

ToLookup登场

static void Main(string[] args)
        {
            List<Product> products = GetList();

            ILookup<string, Product> looks = products.ToLookup(a => a.category);
            //删除产品类别为Garden的产品
            products.RemoveAll(a => a.category == "Garden");
            foreach (IGrouping<string, Product> group in looks)
            {
                Console.WriteLine(group.Key);
                foreach (Product product in group)
                {
                    Console.WriteLine(product);
                }
            }
            //Electronics
            //[1: Electronics - 15]
            //[5: Electronics - 19.9
            //[10: Electronics - 250
            //Groceries
            //[2: Groceries - 40]
            //Garden
            //[3: Garden - 210.3]
            //[8: Garden - 13]
            //Pets
            //[4: Pets - 2.1]
            //[6: Pets - 21.25]
            //[7: Pets - 5.5]
            //Automotive
            //[9: Automotive - 10]
        }

你也可以通过索引器指定键来获得值

 foreach (Product product in looks["Electronics"])
            {
                Console.WriteLine(product);
            }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值