【问题标题】:LINQ Query to compare two values of an object to a list, where both objects must matchLINQ 查询将对象的两个值与列表进行比较,其中两个对象必须匹配
【发布时间】:2018-08-25 03:55:33
【问题描述】:

我有一个账单清单,我有一个汽车清单。每辆车都有两个标识符,它们是账单列表中的单独列(car_init 和 car_nbr)。我需要选择与汽车标识符(首字母和数字)匹配的账单。

例如,如果我有 car_a (car_init: ABC, car_nbr: 123) 和 car_b (car_init:DEF, car_nbr: 456) - 我需要创建与 car_a 和 car_b 匹配的所有账单的列表。

账单列表可以有超过 70k 行,所以我试图找到一种方法,不要为每个查询遍历整个列表 - 因为用户可以在一次操作中搜索多达 200 辆汽车。

这是我目前拥有的,但没有达到预期的结果。目前返回 0 个结果。

bills = bills
    .Where(w => request.CARS
        .Any(car => w.CarInit == car.CarInit && w.CarNbr == car.CarNbr))
    .ToList();

【问题讨论】:

  • 您确实已经检查过,您实际上至少有一行包含您正在测试的值?
  • 将输出变量从“票据”更改为其他变量,以免丢失输入。
  • 是的,我已验证输入与列表中的一行匹配。而且我可以丢失任何不匹配的输入(除非我遗漏了什么)......不应该只留下匹配的行吗?
  • 您对 rows 和 List 的使用让我感到困惑 - 您是在与数据库交谈还是在使用内存中的 List?此外,您意识到使用 LINQ 正在 遍历 Lists?
  • LINQ to objects 永远不会比使用离散逻辑更快而且通常更慢。如果您喜欢函数式编程,它会更简洁,并且更容易理解。至少考虑每个 lambda 是一个方法调用,但在 foreach 中,您将直接执行 lambda 主体而不创建方法。

标签: c# linq


【解决方案1】:

这是一个使用 binarySearch 的解决方案(进行 O(log n) 比较,其中 n 是数组中的元素数),我首先对 car_init 上的票据和汽车进行排序,然后对 car_nbr 进行排序。因为它们都是排序的,所以我们知道我们可以随着搜索的开始移动索引,这使得搜索速度更快。

对于最多 17 次比较中的 70k 钞票,我们找到了元素,享受吧!

using System.Collections.Generic;

namespace ConsoleApp1
{


    class Program
    {

        static void Main(string[] args)
        {
            List<Numbers> bills = new List<Numbers>();
            List<Numbers> cars = new List<Numbers>();

            bills.Add(new Bill("ABC", "123"));
            bills.Add(new Bill("ABC", "654"));
            bills.Add(new Bill("WER", "123"));
            bills.Add(new Bill("ABC", "375"));
            bills.Add(new Bill("ABC", "762"));
            bills.Add(new Bill("WER", "792"));
            bills.Add(new Bill("DDR", "123"));
            bills.Add(new Bill("DEF", "123"));
            bills.Add(new Bill("DEF", "045"));
            bills.Add(new Bill("OLY", "123"));
            bills.Add(new Bill("ABC", "342"));
            bills.Add(new Bill("QWE", "874"));
            bills.Add(new Bill("ABC", "986"));
            bills.Add(new Bill("OLY", "123"));
            bills.Add(new Bill("QWE", "123"));
            bills.Add(new Bill("QWE", "143"));

            CarBillComparer cb = new CarBillComparer();

            cars.Add(new Car("ABC", "375"));
            cars.Add(new Car("QWE", "874"));
            cars.Add(new Car("ABC", "762"));

            bills.Sort(cb);
            cars.Sort(cb);

            List<Numbers> returnBills = new List<Numbers>();

            int index = 0;

            foreach (Car onecar in cars)
            {
                int count = bills.Count - index;
                index = bills.BinarySearch(index, count, onecar, cb);
                if (index > -1)
                {
                    //Item found
                    returnBills.Add(bills[index]);
                }
                else
                {
                    index = ~index;
                }
            }

        }
        public class CarBillComparer : IComparer<Numbers>
        {
            public int Compare(Numbers x, Numbers y)
            {
                int compResult = x.car_init.CompareTo(y.car_init);
                if (compResult == 0)
                {
                    compResult = x.car_nbr.CompareTo(y.car_nbr);
                }
                return compResult;
            }
        }

        public interface Numbers
        {
            string car_init { get; }
            string car_nbr { get; }
        }

        public class Bill:Numbers
        {
            public Bill(string car_init, string car_nbr)
            {
                this.car_init = car_init;
                this.car_nbr = car_nbr;
            }

            public string car_init { get; }
            public string car_nbr { get; }
        }

        public class Car : Numbers
        {
            public Car(string car_init, string car_nbr)
            {
                this.car_init = car_init;
                this.car_nbr = car_nbr;
            }

            public string car_init { get; }
            public string car_nbr { get; }
        }


    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-17
    • 1970-01-01
    • 1970-01-01
    • 2016-06-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多