問題

私が使用している第三者のAPIは、int []型の配列を返します。 readWordsを次のように呼び出しましょう:

 int[] readWords
 

しかし、この返された配列はuint []でなければなりません。 だから私は次のキャストをしています:

 Uint Ulongs = readWords(item => (ulong)item).ToArray();
 

さて、問題は、2つの受信したすべてのint単語をuint64 []に結合する必要がある場合があることです。
または ラムダ式を使用してこれを行うエレガントな方法は何でしょうか?

私は並べ替えの何かを使うことを考えていましたが、私は方法がわかりません:

 Uint64[] longs = readWords
                 .Select(every 2 int into 1 Uint64)
                 .GroupBy(x => ...);
 

2つのintをuint64に組み合わせる必要があることに注意してください。

 Uint64 word0 = (readWords[0] & 0xFFFFFF) | ((Uint64)(readWords[1] & 0xFFFFFF) << 24);
 

例、私たちが持っている場合:

 int[] = new int[]{0x00123456, 0x00456789}
 

結果の64ビット単語は次のようになります。

 0x0000456789123456
 

  ベストアンサー

2つの項目のすべての組み合わせは、Cartesian Join(readWords)です。

 int[] readWords = ...

var result = readWords
  .SelectMany(left => readWords
     .Select(right => /*TODO: put left and right combination here*/))
  .ToArray();
 

2 int sからulongを作成するには、提供したビット操作を使用しましょう。

 (lelf, right) => unchecked(((ulong)left & 0xFFFFFF) | ((ulong)(right & 0xFFFFFF) << 24)))
 

最後に

 int[] readWords = ...

var result = readWords
  .SelectMany(left => readWords
     .Select(right => unchecked(((ulong)left & 0xFFFFFF) | 
                                ((ulong)(right & 0xFFFFFF) << 24))))
  .ToArray(); // materialization, if required
 

見てみましょう:

   int[] readWords = new int[] { 1, 2, 3 };

  var result = readWords
    .SelectMany(left => readWords
      .Select(right => unchecked(((ulong)left & 0xFFFFFF) | 
                                 ((ulong)(right & 0xFFFFFF) << 24))))
    .ToArray();

  string report = string.Join(Environment.NewLine, 
    result.Select(item => item.ToString("x16")));

  Console.WriteLine(report); 
 

結果:

 0000000001000001
0000000002000001
0000000003000001
0000000001000002
0000000002000002
0000000003000002
0000000001000003
0000000002000003
0000000003000003
 

編集:すべての奇妙な項目を組み合わせたい場合、同じアイデア(Cartesian Join):

   int[] readWords = new int[] { 0x00123456, 0x00456789 };

  var result = readWords
    .Where((value, index) => index % 2 == 0)    // even indexes only
    .SelectMany(left => readWords
      .Where((value, index) => index % 2 != 0)  // odd indexes only
      .Select(right => unchecked(((ulong)left & 0xFFFFFF) | 
                                 ((ulong)(right & 0xFFFFFF) << 24))))
    .ToArray();

  string report = string.Join(Environment.NewLine, 
    result.Select(item => item.ToString("x16")));

  Console.Write(report);
 

結果:

   0000456789123456 
 

編集2:しかし、あなたが結合したい場合、Cartesian Joinはここにありません

  item_0 and item_1,
 item_2 and item_3,
 item_4 and item_5,
...
item_2N and item_2N+1,
...
 

(以下のコメントを参照してください。すべてのアイテムを結合しないことに注意してください)単純なSelect:

 var result = Enumerable
  .Range(0, readWords.Length / 2)
  .Select(index => new {
     left = readWords[2 * index],
     right = readWords[2 * index + 1]
   })
  .Select(pair => unchecked(((ulong)(pair.left) & 0xFFFFFF) | 
                            ((ulong)(pair.right & 0xFFFFFF) << 24)))
  .ToArray();
 

  同じタグがついた質問を見る

c#arraysjoinlambdacasting