ラムダ式を使用して、オブジェクトのリストをあるタイプから別のタイプに変換します


224

あるタイプのオブジェクトのリストを読み取り、別のタイプのオブジェクトのリストを生成するforeachループがあります。ラムダ式でも同じ結果が得られると言われました。

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

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

どんな助けでもいただければ幸いです-私はラムダとlinqに初めて感謝します、s


@mmcraeその質問はこれより新しい
Andy Wiesendanger 2016年

回答:


312

以下をお試しください

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

これは、ラムダと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>
アーロンニュートン

220

あなたがいる場合知っているあなたから変換するList<T1>List<T2>、その後List<T>.ConvertAllよりわずかに、より効率的になりますSelect/ ToListそれはで開始する正確なサイズを知っているので:

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

ソースをとしてのみ知っているより一般的なケースでは、/ IEnumerable<T>を使用する方法です。また、LINQのある世界では、最初からもっと慣用的であると主張することできますが、少なくともこのオプションを知っておく価値はあります。SelectToListConvertAll


1
私はこれを行うことができるとは思っていませんでした。なぜなら、私はienumerable(ソースリスト用であり、convertallオプションを提供していません)を扱っていたため、.ToList()を呼び出して、convertall-iを試していますフィルターなしの「どこ」に置くよりも良い
ストラットン

2
なぜあなたはどこが必要ですか?あなただけしか持っていない場合はIEnumerable<T>、電話SelectToListてJaredの答えに従ってください。
Jon Skeet、

私のような他の初心者の場合は、次のようなメソッドを呼び出すこともできますx => buildTargetType(x)
Snekse

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

1
この構文は何ですか?これはラムダに似ていません。いくつかのドキュメントのリンクをいただければ幸いです。おかげで、それはここでうまく機能します
ピエール・ド・レスピーネ2017年

ConvertAllの引数は通常のC#ラムダですよね?
avl_sweden 2018年

1
見栄えは良いですが、使用できる場合(または使用できる場合)にコンテキストが必要です。試してみたところ、cannot cast expression例外が発生しました
Collin M. Barrett

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

5
-1これはキャストが可能である場合にのみ機能し、OPの場合は可能であるように見えます。
Mike Zboray、2012年

期待どおりに動作します!List <object>をList <RealType>に変換するために必要
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
すばらしい...まさに私が探していたもの!厳密には正確ではありません...リスト内の各要素のプロパティが必要なだけですが、あまりスクロールしなくてもランバ構文を取得できました。;)
2015


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

またはconstructorlinq付きSelect

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> 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.