提问者:小点点

使用LINQ将值列表与对象(列表)的属性进行比较


使用LINQ比较两个列表时遇到问题。
我的第一个列表包含对象实例,其中包含感兴趣的属性,要与仅包含值的第二个列表进行比较。
假设我们有:

List<uint> referenceValues = new List<uint>(){1, 2, 3};
and
List<SomeObject> myObject= new List<SomeObject>();

现在SomeObject()类具有Uint类型的属性“value”。
注意,“myObject”列表可能包含比“referenceValues”列表更多的元素,因此我们必须选择“myObject”的适当部分来与“referenceValues”进行比较。

我发现了以下堆栈溢出问题,这是相关的,但不完全是我所追求的:链接

以下是我到目前为止尝试过的,但没有成功的方法:

if (myObject
    .GetRange((int)offset, count)       // Extracted the object of interest from the list
    .Where(x => referenceValues.Equals(x.Value)).Count() == 0)   // Comparing the "Value" properties against the "referenceValues"
{
    // Do something
}

我认为我需要使用“SequenceEqual”,但我不知道如何使用。
欢迎您提供任何建议。

可复制示例:

using System;
using System.Linq;
using System.Collections.Generic;
                    
public class Program
{
    public static void Main()
    {
        int offset = 0;
            
        List<uint> referenceValues = new List<uint>(){1, 2, 3};

        List<SomeObject> myObject= new List<SomeObject>(){new SomeObject(){Value=1}, 
                                                          new SomeObject(){Value=2},
                                                          new SomeObject(){Value=3}};
        
        if (myObject
            .GetRange(offset, referenceValues.Count()-1)       // Extracted the object of interest from the list
            .Where(x => referenceValues.Equals(x.Value)).Count() == referenceValues.Count())   // Comparing the "Value" properties against the "referenceValues"
        {
            // Do something
            Console.WriteLine("Lists are matching!");
        }
        else
        {
            Console.WriteLine("Lists are not matching!");
        }
    }
}

public class SomeObject
{
    public uint Value = 0;
}

根据Guru Stron建议的工作解决方案:

using System;
using System.Linq;
using System.Collections.Generic;
                    
public class Program
{
    public static void Main()
    {
        int offset = 0;
            
        List<uint> referenceValues = new List<uint>(){1, 2, 3};

        List<SomeObject> myObject= new List<SomeObject>(){new SomeObject(){Value=1}, 
                                                          new SomeObject(){Value=2},
                                                          new SomeObject(){Value=3}};
        
        if (myObject.
            GetRange((int)offset, referenceValues.Count())   
            .Select(someObject => someObject.Value)
            .SequenceEqual(referenceValues))
        {
            // Do something
            Console.WriteLine("Lists are matching!");
        }
        else
        {
            Console.WriteLine("Lists are not matching!");
        }
    }
}

public class SomeObject
{
    public uint Value = 0;
}

推荐的Linq表达式书籍:Linq Pocket Reference


共2个答案

匿名用户

如果您希望检查MyObject值的某个子集是否具有某些属性的具体顺序,可以执行如下操作:

bool inOrder = myObject
    .GetRange((int)offset, count)   
    .Select(someObject => someObject.Value)
    .SequenceEqual(referenceValues);

如果只想检查指定的ReferenceValues中是否存在所有值,则可以使用all(如果源范围为空,则返回True):

bool allPresent = myObject
    .GetRange((int)offset, count)   
    .All(someObject => referenceValues.Contains(someObject.Value));

对于没有订购的完全收集匹配,我不知道开箱解决方案,但你可以在这里寻找一个,例如。

匿名用户

if(myObject.Any(x => referenceValues.Contains(x.Value)) {}

我忽略了GetRange部分,但应该没什么区别。