C#以数据结构存储数据

时间:2010-01-04 06:23:42

标签: c# data-structures

我有数据......

1 -> a 10
     b xyz
     c 40 
12 -> a 20
     b os 
8 -> ..............

如何将这些数据存储在数据结构中。哪个DS适合在C#

1,12,8是对象号。 &安培; a,b,c是那里的属性键&价值对。

它是..文件的内部文件表示。 所以我想将它存储起来用于进一步的操作操作。

4 个答案:

答案 0 :(得分:3)

匿名类和隐式类型化数组          通过取消课程需要缩短代码          源代码中的模板和显式类型。 此功能的大缺点元素是只读的。

此示例中没有其他代码丢失,除非将其粘贴到源文件中。

简明的匿名数据结构

    // Strongly-typed anonymous data structure.

    var allData = new[] { // array of parts
        new { Num = 1, Details = new[] { // each part is keyed by object num
                new {KeyChar = 'a', StringValue = "10"} , // key/value pair details
                new {KeyChar = 'b', StringValue = "xyz"} ,
                new {KeyChar = 'c', StringValue = "40"} } 
        },
        new { Num = 12, Details = new[] { 
                new {KeyChar = 'a', StringValue = "20"} ,
                new {KeyChar = 'b', StringValue = "os"} }
        },
        new { Num = 8, Details = new[] { 
            new {KeyChar = 'n', StringValue = "etc..."} }
        }
    };

类型由您的一致数据声明自动推断,并由C#3.x +编译器生成IL。

样本用法

迭代你的数据结构并打印它....

    foreach (var part in allData) {
        Console.WriteLine("Object #" + part.Num + " contains the details: ");
        foreach (var detail in part.Details)
            Console.WriteLine(" - key: " + detail.KeyChar + ", value: " + detail.StringValue);
    }

约定

  • var,对于隐式类型变量,不能在类范围内使用(即创建字段) - 它仅限于方法范围(即作为局部变量)。

  • 使用匿名类型时需要注意一些事项,例如:Can't return anonymous type from method? Really?

  • MSDN documentation描述了一些额外的行为和“陷阱”。

    - 匿名实例是只读的,因此您需要一种不同的方式来存储和保留修改。这可能会使您的要求无效。

  • 然而,将这个答案作为一个选项包含在内是很有趣的,因为我今天学到了新的东西。 :)


编辑/更新:可写版本

(修改以制作等效的可写数据结构)

以上数据结构的等效可写版本如下using System.Collections.Generic;

// Initialization (present data is read/writable)
Dictionary<int, List<Detail>> manageableData = new Dictionary<int, List<Detail>>() 
{
    {1, new List<Detail>() { 
        new Detail {KeyChar = 'a', StringValue="10"},
        new Detail {KeyChar = 'b', StringValue="xyz"}, 
        new Detail {KeyChar = 'c', StringValue="40"}  
        } },

    {12, new List<Detail>() { 
        new Detail {KeyChar = 'a', StringValue="20"},
        new Detail {KeyChar = 'b', StringValue="os"}
        } }
};


// Can continue populating after initialization. E.g...
manageableData.Add(8, new List<Detail>() {
        new Detail {KeyChar = 'n', StringValue="etc..."},
        new Detail {KeyChar = 'z', StringValue="etc..."}
});

声明一个小助手类,使细节数据的初始化更具可读性; Detail助手类替换了简单的KeyValuePair<char, string>。根据口味。

public class Detail {
    public char KeyChar { get; set; }
    public string StringValue { get; set; }
}

...有效地允许我们使用new Detail {KeyChar = 'b', StringValue="xyz"}来初始化详细信息而不是new KeyValuePair<char, string>('b', "xyz")

样本用法

迭代你的数据结构并打印它....

foreach (var part in manageableData) {
    Console.WriteLine("Object #" + part.Key + " contains the details: ");
    foreach (var detail in part.Value)
        Console.WriteLine(" - key: " + detail.KeyChar + ", value: " + detail.StringValue);
}

可写数据结构的另一种变体(不太抽象)

(没有不必要的抽象 - 只是原始集合)

如果没有自定义的Detail类,您可以嵌套像

这样的词典
Dictionary<int, Dictionary<char, string>> data2 = new Dictionary<int, Dictionary<char, string>>() 
{
    {1, new Dictionary<char, string>() { 
        {'a', "10"},
        {'b', "xyz"}, 
        {'c', "40"}  
        } }
};

data2.Add(8, new Dictionary<char,string>() {
        {'n', "etc..."},
        {'z', "etc..."}
});

// SAMPLE USAGE:
// Once again, very minor changes to the mechanism of accessing the data structure:

foreach (var part in data2) {
    Console.WriteLine("Object #" + part.Key + " contains the details: ");
    foreach (var detail in part.Value)
        Console.WriteLine(" - key: " + detail.Key + ", value: " + detail.Value);
}

为了便于阅读,请将“别名”命名为

这是用于存储文件对象和属性的简单嵌套字典方案。

// initialize
Dictionary<int, Dictionary<char, string>> data1 = new Dictionary<int, Dictionary<char, string>>() 
{
    {1, new Dictionary<char, string>() { 
        {'a', "10"},
        {'b', "xyz"}, 
        {'c', "40"}  
        }}
};
// populate 
data1.Add(8, new Dictionary<char, string>() {
    {'n', "etc..."},
    {'z', "etc..."}
    });

制作更具描述性/可读性的版本

有一些方法可以使嵌套数据结构更具可读性。这是一个展示一些可读性差异的示例。可能这不是最聪明的方式,因为它只是为了别名而增加了几种类型但是仍然......

这与上面的数据结构完全相同,但使用“别名”名称

// initialize
FileObjects data2 = new FileObjects() 
{
    {1, new ObjectAttributes() { 
        {'a', "10"},
        {'b', "xyz"}, 
        {'c', "40"}  
        }}
};
// populate 
data2.Add(8, new ObjectAttributes() {
    {'n', "etc..."},
    {'z', "etc..."}
    });

以下“alias”定义有效地将原始Generics(通过继承)重命名为更具描述性的类型,并隐藏Type Parameters。

public class ObjectAttributes : Dictionary<char, string> { }
public class FileObjects : Dictionary<int, ObjectAttributes> { }

在此类方法变得可行之前,您可能需要更多嵌套数据。

答案 1 :(得分:2)

Dictionary<int,Dictionary<string,string>>

编辑: 如果你只有'a''b''c'作为键,你只需使用string [] rec = new string [3]而不是字典。

答案 2 :(得分:0)

数据内容本身只是数据结构选择的一个方面。更重要的指导原则是如何创建,操作和访问数据。

如果您想以有序的方式访问1,2,3等,

List<Dictionary<char, object>>将处理订购,并允许第二级成为您想要的任何类型的内容。

Dictionary<int, Dictionary<string, string>>将允许您快速查找任何顶级1,2,3等...并假设a / 10,b / xyz等...始终编码为字符串。

如果你告诉我们你如何使用这些数据会有所帮助。

答案 3 :(得分:0)

您可以使用的原始结构:

Dictionary<int, Dictionary<char, object>> //or
Dictionary<int, Dictionary<string, object>> //the more common construct, or
Dictionary<int, Dictionary<string, string>> //would require casting on some objects

这可能不适合您的情况,具体取决于您打算如何搜索/访问此内容。

根据数据的含义,特定的类实现和Dictionary实现可能会更好。