2

重複する列を表形式のデータからリストに折りたたむ最もエレガントな方法は何ですか?

例: 単一の差別化列を除いて重複データを含む行を返す SQL クエリを作成しました。

FIRST   LAST      AGE   CAR
Charles Burns     32    Accord
Charles Burns     32    Buick
Charles Burns     32    Lexus
Anders  Hejlsberg 51    Porsche
Anders  Hejlsberg 51    Ferrari
Anders  Hejlsberg 51    Bugatti
Anders  Hejlsberg 51    Pinto

次のようなものを使用してこれらを読み取り、CarInfo オブジェクトに入れます。

while(reader.Read()) {
    first = reader["first"]
    last = reader["last"]
    //...
}
var myData = new CarInfo(first, last, ...);

オブジェクトは次のようになります。

// CarInfo: Need 7 total instances with example data
string first { get; private set; }
string last { get; private set; }
int age { get; private set; }
string car { get; private set; }

私はそれが次のようになりたい:

// CarInfo: Need only 2 instances with example data; 
string first { get; private set; }
string last { get; private set; }
int age { get; private set; }
List<string> cars { get; private set; }

もちろん、これを手動で行うこともできます。たとえば、一意の ID を形成する列を選択し、それらが既にリスト (または辞書など) にあるかどうかを確認しますが、それは非常に面倒です。私は、LINQ がこのデータを美しく折りたたむことができるのではないかと疑うほど LINQ に精通していますが、正確な方法が頭に浮かぶほどには十分に精通していません。

4

3 に答える 3

1

Enumerable.GroupBy 関数を試しましたか? これはあなたが探しているものですか?

class A
        {
            public string a;
            public string b;
            public A(string x, string y)
            {
                a = x;
                b = y;
            }
        }
        static void Main(string[] args)
        {
            A[] tab = { new A("1", "1"), new A("2", "0"), new A("3", "1"), new A("4", "0"), new A("5", "1") };
            var g = tab.GroupBy(x => x.b);
            foreach (var x in g)
            {

                foreach (var y in x)
                {
                    Console.WriteLine(y.a + "/" + y.b);
                }
                Console.WriteLine("----");
            }
            Console.ReadKey();

        }

このコードは次を返します。

{1,1}
{3,1}
{5,1}
--------
{2,0}
{4,0}

フィールド b で要素をグループ化します。

于 2012-05-17T23:36:45.330 に答える
1

LINQ-To-DataSet を読み込んDataTableで使用できます。

List<CarInfo> cars = 
         (from cRow in tblCars.AsEnumerable()
          group cRow by new
          {
              first = cRow.Field<String>("first"),
              last  = cRow.Field<String>("last"),
              age   = cRow.Field<int>("age")
          }into CarGroup
          select new CarInfo() 
          { 
              first = CarGroup.Key.first,
              last  = CarGroup.Key.last,
              age   = CarGroup.Key.age ,
              cars  = CarGroup.Select(cRow => cRow.Field<String>("Car")).ToList()
          }).ToList();

上記は、3 つのフィールドをキーとする匿名型によるグループ化です。次に、CarInfoこれらのフィールドとList<String>グループごとのすべての車を含むプロパティでインスタンスが初期化されます。

于 2012-05-17T23:47:23.510 に答える
0

昨日この問題に直面したばかりですが、SOが使用する美しいオブジェクトマッパーであるDapperを使用していました。親列を子列から分離する列または列のリストを指定する必要がある「分割」アプローチを使用します。

List<CarInfo> parent = new List<CarInfo>();
CarInfo current = null;
var q = _conn.Query<CarInfo, string, CarInfo>(sql
    , (p, c0) =>
    {
        if (current == null || current.Id != p.Id)
        {
            current = p;
        }
        current.Cars.Add(c0);
        parents.Add(current);
        return current;
    }
    , splitOn: "CAR"
);
于 2012-05-17T23:35:02.030 に答える