1

私は「パーツ」のセットを持っています。各パーツには、名前と一連の属性があります。属性は、文字列のキーと値のセットです。例えば:

Part 1
    Width   200
    Depth   400
    Voltage 240V

パーツとその属性を次のような辞書に保存しています。

Dictionary<string, Dictionary<string, string>> parts;

したがって、parts.ContainsKey(part) でパーツが存在するかどうかを確認できます。存在する場合は、parts[part].ContainsKey(attribute) で属性が存在するかどうかを確認できます。これまでのところ、とても平凡です。

ここでやりたいことは、この構造をデータ バインドするか、そうでなければ、各列が属性である一連の行を生成することです。すべてのパーツにすべての属性があるわけではないため、場所によっては「null」が発生します。リストとして、セット全体で見つかったすべての属性のリストにアクセスできます (実際の運用システムには 59 の可能な属性があります)。

最初の列が部品名であると仮定して、一連の行を生成するための私のコードは、以下のかなりぎこちないコードです。文字列のリストのリストになります。パーツごとに 1 つの文字列リスト (パーツごとに 1 つの「行」)。

これには、単純なワンライナーのLinqステートメントがあると確信しています。これを使用してリストまたはデータ グリッドにデータ バインドし、ある時点で表示できることを願っています。誰でも私を助けてくれますか?

以下に完全な再現を提供します (新しい C# コンソール プロジェクトを追加します)。いくつかのサンプル データを使用します。

using System;
using System.Collections.Generic;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {              
            // The set of parts.

            Dictionary<string, Dictionary<string, string>> hashPartToAttributes = new Dictionary<string,Dictionary<string,string>>();

            hashPartToAttributes.Add("Part 1", new Dictionary<string,string>());
            hashPartToAttributes.Add("Part 2", new Dictionary<string,string>());
            hashPartToAttributes.Add("Part 3", new Dictionary<string,string>());
            hashPartToAttributes.Add("Part 4", new Dictionary<string,string>());

            // Add in all attributes for all of the parts.

            {
                hashPartToAttributes["Part 1"].Add("Width", "200");
                hashPartToAttributes["Part 1"].Add("Height", "400");
                hashPartToAttributes["Part 1"].Add("Depth", "600");

                hashPartToAttributes["Part 2"].Add("Width", "300");
                hashPartToAttributes["Part 2"].Add("Height", "700");
                hashPartToAttributes["Part 2"].Add("Depth", "100");
                hashPartToAttributes["Part 2"].Add("Voltage", "240V");

                hashPartToAttributes["Part 3"].Add("Voltage", "110V");
                hashPartToAttributes["Part 3"].Add("Bandwidth", "25");
                hashPartToAttributes["Part 3"].Add("Frequency", "5");
                hashPartToAttributes["Part 3"].Add("Height", "900");

                hashPartToAttributes["Part 4"].Add("Width", "150");
                hashPartToAttributes["Part 4"].Add("Height", "740");
                hashPartToAttributes["Part 4"].Add("Depth", "920");
                hashPartToAttributes["Part 4"].Add("Voltage", "240V");
                hashPartToAttributes["Part 4"].Add("Bandwidth", "40");
                hashPartToAttributes["Part 4"].Add("Frequency", "5");
            }

            // The complete set of all attributes (column headings)

            List<string> attributeKeys = new List<string>() {
                "Width", "Height", "Depth", "Voltage", "Bandwidth", "Frequency"
            };

            // Now construct a row for each part.

            List<List<string>> rows = new List<List<string>>();

            foreach (string part in hashPartToAttributes.Keys)
            {
                List<string> row = new List<string>() { part };

                foreach (string key in attributeKeys)
                {
                    Dictionary<string, string> attributes = hashPartToAttributes[part];

                    if (attributes != null && attributes.ContainsKey(key))
                    {
                        row.Add(attributes[key]);
                    }
                    else
                    {
                        row.Add(null);
                    }
                }

                rows.Add(row);
            }           

            // Print out headings.

            Console.Write("{0, -10}", "Part");

            foreach (string heading in attributeKeys)
            {
                Console.Write("{0, -10}", heading);
            }

            Console.WriteLine();
            Console.WriteLine();

            // Print out the rows

            foreach (List<string> row in rows)
            {
                foreach (string item in row)
                {
                    if (item != null)
                    {
                        Console.Write("{0, -10}", item);
                    }
                    else
                    {
                        Console.Write("{0, -10}", "-");
                    }
                }

                Console.WriteLine();
            }
        }
    }
}
4

1 に答える 1

4

単純な LINQ ステートメントは存在しませんが、次を使用できます。

hashPartToAttributes.Select(
    p => new [] { p.Key }.Concat(
        attributeKeys.GroupJoin(p.Value, ak => ak, a => a.Key,
            (ak, a) => a.Select(x => x.Value).SingleOrDefault())
                     .DefaultIfEmpty())
                         .ToArray()
                           )
于 2013-05-03T11:51:23.317 に答える