1

次のクエリを検討してください。

var ds = (from t1 in list1
          from t2 in list2
          select new {t1.Name, t2.Name}
         ).ToList();

これは次のようなものを返します: (大まかな表現)

Name1, InnerName1
Name1, InnerName2
Name2, InnerName1
Name2, InnerName2

私が取得したいのは次のとおりです。

Name1, InnerName1
Null, InnerName2
Name2, InnerName1
Null, InnerName2.

つまり、リストに既に t1.Name がある場合、残りの t1 の結果に null または空の文字列が必要です。

結果をループできることは既に知っていますが、これをデータソースとして使用しており、セットベースで何かをしたいと考えています。

単一のクエリでこれを達成する方法はありますか?

4

5 に答える 5

2

Linq-to-Objects を使用すると仮定すると、次のようなことができます。

string previous = null;
var results = 
    (from t1 in list1
     from t2 in list2
     select new {
         Name1 = (previous == t1.Name) ? null : (previous = t1.Name), 
         Name2 = t2.Name 
     })
    .ToList();

しかし、それは副作用に依存しており、特にエレガントではありません。あなたは次のようなものを好むかもしれません:

var result = 
    (from t1 in list1
     select 
       list2.Take(1)
         .Select(t2 => new { Name1 = t1.Name,  Name2 = t2.Name })
         .Concat(list2.Skip(1)
           .Select(t2 => new { Name1 = (string)null, Name2 = t2.Name }))
    .SelectMany(x => x)
    .ToList();
于 2013-10-01T05:28:49.920 に答える
1

ここでクロス結合が必要だと思います。これを試して。

//will get null values for both
    var ds = (from t1 in list1
              join t2 in list2 into t3
              from objt3 in t3.DefaultIfEmpty()
              select new {t1.Name, objt3.Name}
             ).ToList();

編集:

//will get null values for second list
    var ds = (from t1 in list1
              join t2 in list2 into t3
              from objt3 in t3.DefaultIfEmpty()
              where t1 != null
              select new {t1.Name, objt3.Name}
             ).ToList();

更新しました:

//will get null values for second list
    var ds = (from t1 in list1
              where t1 != null
              join t2 in list2 into t3
              from objt3 in t3.DefaultIfEmpty()
              select new {t1.Name, objt3.Name}
             ).ToList();
于 2013-10-01T05:09:59.350 に答える
1

シーケンスの最初の項目を別の方法で処理するにはSelect、インデックスでそのパスのオーバーロードを使用するだけで、ゼロと比較できます。

そのオーバーロードはクエリ構文ではアクセスできず、クエリは、混合して一致させるよりも、すべてのメソッド構文で少し見栄えがよくなります。

var query = list1.SelectMany(t1 => list2.Select((t2, i) => new
{
    Name1 = i == 0 ? t1.Name : null,
    Name2 = t2.Name
}));
于 2013-10-02T17:08:59.607 に答える