简体   繁体   中英

Using linq to get part of a list with specific object property

I have:

List<int> A; //ids list
List<myObject> B;

myObject has 2 properties:

int id;
string state;

List B includes all the ids of List A and more.

I would like to get List<myObject> C which is built of all the ids from List A which are also in state='Idle'.

What is the shortest linq query for this?

you can use LINQ Join + Where to do it

void Main()
{
    List<int> A = new List<int>() {1,2}; //ids list
    List<myObject> B = new List<myObject>()
    {
        new myObject{Id=1,state="Run"},
        new myObject{Id=2,state="Idle"},
        new myObject{Id=3,state="Idle"},
    };

    var expectedResult = from t1 in B
        join t2 in A on t1.Id equals t2
        where t1.state == "Idle"
        select t1;
}

// Define other methods and classes here
class myObject
{
    public int Id { get; set; }
    public string state { get; set; }
}

在此处输入图片说明

Here a Step-by-step example with example-data:

class MyObject
{
    public int Id { get; set; }
    public string State { get; set; }
}

public static void Main(string[] args)
{
    List<int> A = new List<int>()
    {
        1,
        2
    };

    List<MyObject> B = new List<MyObject>()
    {
        new MyObject() { Id = 1, State = "Idle" },
        new MyObject() { Id = 2, State = "Running" },
        new MyObject() { Id = 3, State = "Idle" },
    };

    // Where to filter elements by contidion
    var objectsFromA = B.Where(b => A.Contains(b.Id)); 

    Console.WriteLine("Filtered with Id-List 'A': " + string.Join(", ", objectsFromA.Select(s => "\"" + s.Id + ": " + s.State + "\"")));

    var onlyIdles = objectsFromA.Where(o => o.State == "Idle");

    Console.WriteLine("Filtered only Idle: " + string.Join(", ", onlyIdles.Select(s => "\"" + s.Id + ": " + s.State + "\"")));

    // Or in one single Where:
    Console.WriteLine("Filtered only Idle: " + string.Join(", ", B.Where(b => A.Contains(b.Id) && b.State == "Idle").Select(s => "\"" + s.Id + ": " + s.State + "\"")));
}

You can use Enumerable.Any to filter B by the IDs in A and in the same query check for the idle state:

var idleObjectsQry =
    from myObject in B
    where A.Any(id => myObject.id = id) && (myObject.state == "Idle")
    select myObject;
List<myObject> C = idleObjectsQry.ToList();

You could also use Join , but in LINQ you generally prefer composition over join, since it is more flexible.

List<myObject> C = B.Where(b => A.Contains(b.Id) && b.state == "Idle").ToList();

尝试像这样使用

List<myObject> C = B.where(x=>x.state =="Idle" && A.contains(x.Id)).select B.ToList();

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM