简体   繁体   中英

How to map two different lists to one list?

I have two lists of Generic types A and B :

public class A {
    int type;
    string params;
    bool isActive;
}

public class B {
    int type;
}

How could I map them into one list of type A where B.type == A.type (not A.type == B.type !!) using linq?

Instances of class B contain int values that can be deleted or added whereas instances of class A contain values from my db.

So for example:

A[0] = {1, "11", true}, A[1] = {2, "22", true}, A[2] = {3, "33", false}

and

B = {2, 3}

The desired result consists of A[1] and A[2] .

You want to join both lists, so find all A which are in both lists?

var query = from a in aList
            join b in bList
            on a.type equals b.type
            select a;
List<A> resultList = query.ToList();

It sounds like what you mean is "filter the items from the first list by checking a property against a second list" - in which case, I would suggest:

  1. build an index from the second list:

     // create an index of the "type"s to look for var index = new HashSet<int>(bList.Select(x => x.type)); 
  2. use this to filter the data

     // filter the primary list to values from the index var matches = aList.FindAll(x => index.Contains(x.type)); 

This will very efficiently give you a list of just the A data that has corresponding values in the bList .

Here it is runnable:

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

class Program
{
    public class A
    {
        public int type;
        public string @params;
        public bool isActive;
    }

    public class B
    {
        public int type;
    }
    static void Main()
    {
        var aList = new List<A>
        {
            new A { type = 1, @params = "11", isActive = true },
            new A { type = 2, @params = "22", isActive = true },
            new A { type = 3, @params = "33", isActive = false },
        };
        var bList = new List<B>
        {
            new B { type = 2 },
            new B { type = 3 },
        };
        // create an index of the "type"s to look for
        var index = new HashSet<int>(bList.Select(x => x.type));

        // filter the primary list to values from the index
        var matches = aList.FindAll(x => index.Contains(x.type));

        foreach (var match in matches)
        {
            Console.WriteLine($"{match.type}, {match.@params}, {match.isActive}");
        }
    }
}

with output:

2, 22, True
3, 33, False

这是你想要的 !?

var result = arrayA.Where(a => arrayB.Select(b => b.type).Contains(a.type)).ToArray();

If you have two sequences, where both sequence have a value that should match, and you want to take zero or more properties form the first sequence and zero or more properties from the second sequence you use Enumerable.Join.

The syntax seems a bit difficult, but if used more often you get accustomed to it.

Suppose in your example you have a sequence of A objects and a sequence of B objects:

IEnumerable<A> myAobjects = ...
IEnumerable<B> myBobjects = ...

// do the join:
myAObjects.Join(myBobjects,  // join the two sequences
myAobject => myAobject.type, // from the A sequence take property type
myBobject => myBobject.type, // from the B sequence also take property type
(myAobject, myBobject) =>    // whenever the values of these properties equal, take:
 ...);

The dots will be filed with what you want from the combination of a myAobject and a myBobject that have the same value for property type. Your question is simple: whenever a myAobject.type matches a myBobject.type, you want the complete myAObject. In that case the last part of the join is:

(myAobject, myBobject) => myAobject

If you wanted something else returned you would use something like:

(myAobject, myBobject) => new
{
    MyParams = myAobject.Params,
    MyOtherValue = myBObject.type,
}

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