简体   繁体   English

使用 lambda 表达式将对象列表从一种类型转换为另一种类型

[英]convert a list of objects from one type to another using lambda expression

I have a foreach loop reading a list of objects of one type and producing a list of objects of a different type.我有一个 foreach 循环读取一种类型的对象列表并生成不同类型的对象列表。 I was told that a lambda expression can achieve the same result.有人告诉我 lambda 表达式可以达到相同的结果。

var origList = List<OrigType>(); // assume populated
var targetList = List<TargetType>(); 

foreach(OrigType a in origList) {
    targetList.Add(new TargetType() {SomeValue = a.SomeValue});
}

Try the following尝试以下

var targetList = origList
  .Select(x => new TargetType() { SomeValue = x.SomeValue })
  .ToList();

This is using a combination of Lambdas and LINQ to achieve the solution.这是使用 Lambdas 和 LINQ 的组合来实现解决方案。 The Select function is a projection style method which will apply the passed in delegate (or lambda in this case) to every value in the original collection. Select 函数是一种投影样式方法,它将传入的委托(在本例中为 lambda)应用于原始集合中的每个值。 The result will be returned in a new IEnumerable<TargetType> .结果将在新的IEnumerable<TargetType> The .ToList call is an extension method which will convert this IEnumerable<TargetType> into a List<TargetType> . .ToList 调用是一个扩展方法,它将将此IEnumerable<TargetType>转换为List<TargetType>

If you know you want to convert from List<T1> to List<T2> then List<T>.ConvertAll will be slightly more efficient than Select / ToList because it knows the exact size to start with:如果您知道要从List<T1>转换为List<T2>那么List<T>.ConvertAll将比Select / ToList稍微高效一点,因为它知道开始时的确切大小:

target = orig.ConvertAll(x => new TargetType { SomeValue = x.SomeValue });

In the more general case when you only know about the source as an IEnumerable<T> , using Select / ToList is the way to go.在更一般的情况下,当您只知道作为IEnumerable<T>的源时,使用Select / ToList是要走的路。 You could also argue that in a world with LINQ, it's more idiomatic to start with... but it's worth at least being aware of the ConvertAll option.可以争辩说,在使用 LINQ 的世界中,开始时更惯用……但至少值得了解ConvertAll选项。

var target = origList.ConvertAll(x => (TargetType)x);
List<target> targetList = new List<target>(originalList.Cast<target>());

我相信这样的事情应该有效:

origList.Select(a => new TargetType() { SomeValue = a.SomeValue});

Here's a simple example..这是一个简单的例子..

List<char> c = new List<char>() { 'A', 'B', 'C' };

List<string> s = c.Select(x => x.ToString()).ToList();
var list1 = new List<Type1>();
var list2 = new List<Type2>();

list1.ForEach(item => list2.Add(new Type2() { Prop1 = value1 }));

Assume that you have multiple properties you want to convert.假设您有多个要转换的属性。

public class OrigType{
    public string Prop1A {get;set;}
    public string Prop1B {get;set;}
}

public class TargetType{
    public string Prop2A {get;set;}
    public string Prop2B {get;set;}
}

var list1 = new List<OrigType>();
var list2 = new List<TargetType>();

list1.ConvertAll(x => new OrigType { Prop2A = x.Prop1A, Prop2B = x.Prop1B })

Or with a constructor & linq with Select :或者使用带有Selectconstructorlinq

public class TargetType {
  public string Prop1 {get;set;}
  public string Prop1 {get;set;}

  // Constructor
  public TargetType(OrigType origType) {
    Prop1 = origType.Prop1;
    Prop2 = origType.Prop2;
  }
}

var origList = new List<OrigType>();
var targetList = origList.Select(s=> new TargetType(s)).ToList();  

The Linq line is more soft! Linq线更软! ;-) ;-)

If you need to use a function to cast:如果您需要使用函数进行转换:

var list1 = new List<Type1>();
var list2 = new List<Type2>();

list2 = list1.ConvertAll(x => myConvertFuntion(x));

Where my custom function is:我的自定义函数在哪里:

private Type2 myConvertFunction(Type1 obj){
   //do something to cast Type1 into Type2
   return new Type2();
}

对于类似类型的类。

List<targetlist> targetlst= JsonConvert.DeserializeObject<List<targetlist>>(JsonConvert.SerializeObject(<List<baselist>));

If casting when mapping from one list to another is required, from convertall, you can call a function to test the casting.如果需要在从一个列表映射到另一个列表时进行转换,您可以从 convertall 调用 function 来测试转换。

public int StringToInt(String value)
        {
            try
            {
                return Int32.Parse(value);
            }
            catch (Exception ex)
            {
                return -1;
            }
        }
        [Fact]
        public async Task TestConvertAll()
        { 
            List<String> lstString = new List<String>{"1","2","3","4","5","6","7","8","9","10" };

            List<int> lstInt = lstString.ConvertAll(new Converter<String, int>(StringToInt));
            foreach (var item in lstInt)
            {
                output.WriteLine("{0}", item);
            }
            if (lstInt.Count()>0) {
                Assert.True(true);
            }
        }

If the types can be directly cast this is the cleanest way to do it:如果类型可以直接转换,这是最干净的方法:

var target = yourList.ConvertAll(x => (TargetType)x);

If the types can't be directly cast then you can map the properties from the orginal type to the target type.如果类型不能直接转换,那么您可以将属性从原始类型映射到目标类型。

var target = yourList.ConvertAll(x => new TargetType { SomeValue = x.SomeValue });

We will consider first List type is String and want to convert it to Integer type of List.我们将首先考虑 List 类型是 String 并希望将其转换为 List 的 Integer 类型。

List<String> origList = new ArrayList<>(); // assume populated

Add values in the original List.在原始列表中添加值。

origList.add("1");
origList.add("2");
    origList.add("3");
    origList.add("4");
    origList.add("8");

Create target List of Integer Type创建整数类型的目标列表

List<Integer> targetLambdaList = new ArrayList<Integer>();
targetLambdaList=origList.stream().map(Integer::valueOf).collect(Collectors.toList());

Print List values using forEach:使用 forEach 打印列表值:

    targetLambdaList.forEach(System.out::println);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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