通过将其他属性与其他列表进行比较来从源列表中选择ID

时间:2019-05-20 21:18:02

标签: c# generics lambda generic-list

我有两个List个项目类对象,例如;

SourceList

Id  DateTime
1   21.05.2019 10:00:00
2   21.05.2019 10:10:00
3   21.05.2019 10:20:00
4   21.05.2019 10:30:00
5   21.05.2019 10:40:00
6   21.05.2019 10:50:00
7   21.05.2019 11:00:00

目的地列表

Id  DateTime
1   21.05.2019 9:00:00
3   21.05.2019 10:25:00
5   21.05.2019 10:45:00
7   21.05.2019 10:30:00
9   21.05.2019 10:40:00
11  21.05.2019 10:50:00

我会从Id中选择SourceList个来找到两者:

  • a。 Id上存在SourceListDestinationList上不存在的{(更不用说,这个本身很容易)
  • b。这两个列表中都存在Id个,但仅检索其SourceList上日期时间较大的日期

因此,示例结果将是的并集;

a. 2,4,6
b. 1,7

2,4,6,1,7

使用lambda表达式最有效的方法是什么。

谢谢

2 个答案:

答案 0 :(得分:1)

loginFailed (error) {
  console.log(error) // the server side data from axios.
}

输出:

using System;
using System.Collections.Generic;
using System.Linq;

namespace ConsoleApp
{
    class Program
    {
        static void Main(string[] args)
        {
            var source = new[]
            {
                new Entry { Id = 1, DateTime = DateTime.Parse("21.05.2019 10:00:00") },
                new Entry { Id = 2, DateTime = DateTime.Parse("21.05.2019 10:10:00") },
                new Entry { Id = 3, DateTime = DateTime.Parse("21.05.2019 10:20:00") },
                new Entry { Id = 4, DateTime = DateTime.Parse("21.05.2019 10:30:00") },
                new Entry { Id = 5, DateTime = DateTime.Parse("21.05.2019 10:40:00") },
                new Entry { Id = 6, DateTime = DateTime.Parse("21.05.2019 10:50:00") },
                new Entry { Id = 7, DateTime = DateTime.Parse("21.05.2019 11:00:00") }
            };

            var destination = new[]
            {
                new Entry { Id = 1, DateTime = DateTime.Parse("21.05.2019 09:00:00") },
                new Entry { Id = 3, DateTime = DateTime.Parse("21.05.2019 10:25:00") },
                new Entry { Id = 5, DateTime = DateTime.Parse("21.05.2019 10:45:00") },
                new Entry { Id = 7, DateTime = DateTime.Parse("21.05.2019 10:30:00") },
                new Entry { Id = 9, DateTime = DateTime.Parse("21.05.2019 10:40:00") },
                new Entry { Id = 11, DateTime = DateTime.Parse("21.05.2019 10:50:00") }
            };

            var comparer = new EntryComparer();
            var partA = source.Except(destination, comparer);
            var partB = source.Intersect(destination, comparer)
                              .Where(i => source.First(j => j.Id == i.Id).DateTime >
                                          destination.First(j => j.Id == i.Id).DateTime);
            var result = partA.Concat(partB);
            foreach (var i in result)
                Console.WriteLine(i);
        }

        private class Entry
        {
            public int Id { get; set; }
            public DateTime DateTime { get; set; }

            public override string ToString() => $"{Id} {DateTime}";
        }

        private class EntryComparer : IEqualityComparer<Entry>
        {
            public bool Equals(Entry x, Entry y) => x.Id.Equals(y.Id);

            public int GetHashCode(Entry obj) => obj.Id.GetHashCode();
        }
    }
}

答案 1 :(得分:1)

有两种方法。一种是编写自己的EqualityComparator并使用ExceptIntersect列出结果,如上述结果中的@Alex所示,这是可靠的代码,并且也是可重复使用的,但是,如果您要寻找快速的结果,则可以使用whereany和/或两者的组合使用以下内容。

因此,要获得结果,linq查询将如下所示

a) var resultWhereIdsExistsInSourceListButNotOnDestination = sourceList
.Where(l1 => !destinationList.Any(l2 => l2.Id == l1.Id))
.Select(l => l.Id);

b) var resultWhereIdsExistInBothWithDateGreaterInSourceList =
 sourceList
.Where(l1 => destinationList.Any(l2 => l2.Id == l1.Id && l1.Date > l2.Date))
.Select(l => l.Id);

c) var combinedResult = resultWhereIdsExistsInSourceListButNotOnDestination
   .Union(resultWhereIdsExistInBothWithDateGreaterInSourceList);

小提琴链接https://dotnetfiddle.net/AGwFlC#

注意:我已经使用了自己的样本数据。同样,只是为了将ForEach用于可读性,我已经将.ToList()用于演示目的。不需要每次都将可枚举转换为列表。纯粹出于演示目的

        using System;
        using System.Collections.Generic;
        using System.Linq;

        public class Program
        {
            public static void Main()
            {
                var sourceList = new List<Foo>()
                {new Foo()
                {Id = 1, Date = DateTime.Now}, new Foo()
                {Id = 2, Date = DateTime.Now.AddDays(5)}, new Foo()
                {Id = 3, Date = DateTime.Now.AddDays(3)}, new Foo()
                {Id = 4, Date = DateTime.Now}, new Foo()
                {Id = 5, Date = DateTime.Now}};
                var destinationList = new List<Foo>()
                {new Foo()
                {Id = 2, Date = DateTime.Now}, new Foo()
                {Id = 3, Date = DateTime.Now}, new Foo()
                {Id = 4, Date = DateTime.Now}, new Foo()
                };

                Console.WriteLine("--IDs IN SOURCE LIST BUT NOT IN DESTINATION--------");
                var resultWhereIdsExistsInSourceListButNotOnDestination = 
sourceList
.Where(l1 => !destinationList.Any(l2 => l2.Id == l1.Id)).Select(l => l.Id).ToList();
                resultWhereIdsExistsInSourceListButNotOnDestination.ForEach(r => Console.WriteLine(r));
                Console.WriteLine("--IDs IN BOTH WHERE THE DATE IN SOURCE LIST IS GREATER--------");
                var resultWhereIdsExistInBothWithDateGreaterInSourceList = sourceList
    .Where(l1 => destinationList.Any(l2 => l2.Id == l1.Id && l1.Date > l2.Date)).Select(l => l.Id).ToList();
                resultWhereIdsExistInBothWithDateGreaterInSourceList.ForEach(r => Console.WriteLine(r));

                Console.WriteLine("------------------ UNINON-------------------------------------");
                resultWhereIdsExistsInSourceListButNotOnDestination
    .Union(resultWhereIdsExistInBothWithDateGreaterInSourceList).ToList().ForEach(r => Console.WriteLine(r));


            }
        }

        public class Foo
        {
            public DateTime Date
            {
                get;
                set;
            }

            public int Id
            {
                get;
                set;
            }
        }

        ;