Jun 6, 2010

C# : Flatten()のようなもの

RubyでいうArray#flattenに相当するメソッドがC#には無いということで、似たものを書いてみたのがこちら。System.Arrayに対する拡張メソッドとなっています。

  1. using System;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4.  
  5. namespace FlattenTest
  6. {
  7.     public static class ExtensionMethods
  8.     {
  9.         /// Ref.: Flatten Ruby method in C# - Stack Overflow
  10.         ///   http://stackoverflow.com/questions/197081/flatten-ruby-method-in-c
  11.         private static IEnumerable FlattenAux(this IEnumerable array)
  12.         {
  13.             foreach (var item in array)
  14.             {
  15.                 if (item is IEnumerable)
  16.                 {
  17.                     foreach (var subitem in FlattenAux((IEnumerable)item))
  18.                     {
  19.                         yield return subitem;
  20.                     }
  21.                 }
  22.                 else
  23.                 {
  24.                     yield return item;
  25.                 }
  26.             }
  27.         }
  28.  
  29.         /// Returns a one-dimensinal flattening of given array.
  30.         public static System.Array Flatten(this System.Array array)
  31.         {
  32.             var al = new ArrayList(array.Length);
  33.             foreach (var v in FlattenAux(array))
  34.                 al.Add(v);
  35.             return al.ToArray(al[0].GetType());
  36.         }
  37.     }
  38.  
  39.     class Program
  40.     {
  41.         static void Main(string[] args)
  42.         {
  43.             float[, ,] p0 = new float[3,2,2];
  44.             float[][][] p1 = new float[3][][] {
  45.                 new float[2][] { new float[2]new float[2] },
  46.                 new float[2][] { new float[2]new float[2] },
  47.                 new float[2][] { new float[2]new float[2] }
  48.             };
  49.             for (int i = 0; i < 3; ++i)
  50.                 for (int j = 0; j < 2; ++j)
  51.                     for (int k = 0; k < 2; ++k)
  52.                         p0[i, j, k] = p1[i][j][k] = 100 * i + 10 * j + k;
  53.  
  54.             float[] fp0 = (float[])p0.Flatten();
  55.             for (int i = 0; i < fp0.Length; ++i)
  56.                 Console.Write("{0} ", fp0[i]);
  57.             Console.WriteLine();
  58.  
  59.             float[] fp1 = (float[])p1.Flatten();
  60.             for (int i = 0; i < fp1.Length; ++i)
  61.                 Console.Write("{0} ", fp1[i]);
  62.             Console.WriteLine();
  63.         }
  64.     }
  65. }