람다 식을 사용하여 객체 목록을 한 유형에서 다른 유형으로 변환


224

한 유형의 객체 목록을 읽고 다른 유형의 객체 목록을 생성하는 foreach 루프가 있습니다. 람다식이 동일한 결과를 얻을 수 있다고 들었습니다.

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

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

도움이 될 것입니다-나는 lambda와 linq를 처음 사용합니다.


@mmcrae는 질문은 이것보다 새로운 것을
앤디 Wiesendanger

답변:


312

다음을 시도하십시오

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

솔루션을 달성하기 위해 Lambdas와 LINQ의 조합을 사용하고 있습니다. Select 함수는 전달 된 대리자 (이 경우 람다)를 원본 컬렉션의 모든 값에 적용하는 투영 스타일 방법입니다. 결과는 새로운로 반환됩니다 IEnumerable<TargetType>. .ToList 호출은 이것을. IEnumerable<TargetType>로 변환하는 확장 메소드입니다 List<TargetType>.


구체적인 구현 없이이 작업을 수행 할 수 TargetType있습니까? 나는 다음과 같은 결과 List<ISearchEntity> results = myIQueryable.Select(x => (ISearchEntity) new TargetType { MyField = "Field value is " + x.TargetField }).ToList();를 얻었습니다. 목표는 유형의 객체를 얻는 것이 었습니다List<ISearchEntity>
Aaron Newton 1

220

당신이 경우 알고 당신이 변환하고자 List<T1>하는 List<T2>List<T>.ConvertAll보다 약간 더 효율적입니다 Select/ ToList이 시작하는 정확한 크기를 알고 있기 때문에 :

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

당신이 단지 같은 소스에 대해 알고 더 일반적인 경우 IEnumerable<T>, 사용 Select/ ToList길을 가야하는 것입니다. 당신은 또한 LINQ 함께 세계에서, 그것은 시작하는 더 관용적 있다고 주장 ...하지만 적어도 그것의 가치는 인식하고 ConvertAll옵션을 선택합니다.


1
처음에는 ienumerable (소스 목록의 경우 convertall 옵션을 제공하지 않음)을 다루었으므로 .ToList ()을 호출했고 이제는 convertall을 시도하고 있기 때문에이 작업을 수행 할 수 있다고 생각하지 않았습니다. 필터링하지 않는 'where'를 넣는 것보다 낫습니다
Stratton

2
왜 어디가 필요할까요? 만 가지고있는 경우에 IEnumerable<T>그럼 그냥 전화 SelectToList제라드의 대답에 따라.
Jon Skeet

나와 같은 다른 초보자를 위해 다음과 같은 방법을 호출 할 수도 있습니다.x => buildTargetType(x)
Snekse

55
var target = origList.ConvertAll(x => (TargetType)x);

1
이 구문은 무엇입니까? 이것은 람다와 비슷하지 않습니다. 일부 문서 링크를 주시면 감사하겠습니다. 감사합니다, 여기에서 잘 작동합니다
Pierre de LESPINAY

ConvertAll에 대한 논쟁은 일반적인 C # 람다입니다.
avl_sweden

1
멋지게 보이지만 언제 사용할 수 있는지에 대한 컨텍스트가 필요합니다. 방금 시도했지만 cannot cast expression예외 가 발생했습니다
Collin M. Barrett

31
List<target> targetList = new List<target>(originalList.Cast<target>());

5
-1 캐스팅이 가능한 경우에만 작동하며 OP의 경우에는 그렇게 나타납니다.
Mike Zboray

예상대로 작동합니다!
Elo

20

나는 이와 같은 것이 효과가 있다고 믿는다.

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

1
.ToList()마지막 에 a를 추가해야합니다 . 그렇지 않으면 IEnumerable을 제공합니다.
MattD

10

다음은 간단한 예입니다.

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

List<string> s = c.Select(x => x.ToString()).ToList();

1
굉장한 ... 정확히 내가 찾던 것! 글쎄요, 정확히 ... 목록에있는 각 요소의 속성을 원했지만 너무 멀리 스크롤하지 않고도 람바 구문을 줬습니다. ;)
오류

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

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

3

변환하려는 여러 속성이 있다고 가정합니다.

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 })

2

또는 constructor& linqSelect:

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();  

Linq라인은 더 부드럽고! ;-)


0

캐스트하기 위해 함수를 사용해야하는 경우 :

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

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

내 사용자 정의 기능은 다음과 같습니다.

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

0

유사한 유형 클래스.

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


대단히 감사합니다. 그것은 서버에 대한 지옥만큼 비싸고 모범 사례에 따르지는 않지만 훌륭하게 작동합니다. 여러 프로 시저가 결과에서 동일한 5 개의 열을 반환 할 때 EF 데이터베이스 첫 번째 클래스를 변환하는 데 사용했으며 프로 시저의 다른 "where 절"에 대해서만 사용했습니다. 데이터베이스에서 테이블 형식을 만들어야했지만 그 디자이너는 아니 었습니다.
jo1storm

-1

유형을 직접 캐스트 할 수있는 경우 가장 깨끗한 방법입니다.

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

유형을 직접 캐스트 할 수없는 경우 특성을 원래 유형에서 대상 유형으로 맵핑 할 수 있습니다.

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

-1

첫 번째 List 유형이 String 인 것을 고려하여 Integer 유형의 List로 변환하려고합니다.

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

원본 목록에 값을 추가하십시오.

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

정수 유형의 대상 목록 작성

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

forEach를 사용하여 목록 값 인쇄 :

    targetLambdaList.forEach(System.out::println);
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.