繁体   English   中英

C#以数据结构存储数据

[英]C# storing data in data structure

我有类似的数据

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

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

1,12,8是对象编号。 &a,b,c是there属性键和值对。

它是..文件的内部文件表示。 因此,我想将其存储以进行进一步的操作。

通过消除源代码中对类模板和显式类型的需求,匿名类和隐式类型的数组使代码更短。 此功能的一大缺点是元素是只读的。

除了将其粘贴到源文件中之外,此示例中没有其他代码。

简洁的匿名数据结构

    // 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不能在类范围内使用(即创建字段)-限于方法范围内(即作为局部变量)。

  • 使用匿名类型时,需要注意一些事项,例如: 无法从方法返回匿名类型? 真?

  • MSDN文档描述了一些其他行为和“陷阱”。

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

  • 但是 ,将这个答案作为选项很有趣,因为今天我什么也没学到新东西。 :)


编辑/更新:可写版本

(进行修改以形成等效的可写数据结构)

下面是上述数据结构的等效可写版本, 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 helper类将替换为简单的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..."}
    });

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

有一些方法可以使嵌套数据结构更具可读性。 这是一个显示一些可读性差异的示例。 这可能不是最聪明的方法,因为它只是为了别名而添加了两个Types,但是...

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

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

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

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

在这种方法可行之前,您可能需要更多的嵌套数据。

Dictionary<int,Dictionary<string,string>>

编辑:如果仅将“ a”,“ b”,“ c”作为键,则只需使用string [] rec = new string [3]而不是字典。

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

如果要以有序的方式访问1、2、3等,则List<Dictionary<char, object>>将处理排序,并允许第二级成为所需的任何类型的内容。

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

如果您告诉我们您如何使用此数据,将会有所帮助。

您可以使用的原始结构:

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实现可能会更好。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM