我有数据......
1 -> a 10
b xyz
c 40
12 -> a 20
b os
8 -> ..............
如何将这些数据存储在数据结构中。哪个DS适合在C#。
1,12,8是对象号。 &安培; a,b,c是那里的属性键&价值对。
它是..文件的内部文件表示。 所以我想将它存储起来用于进一步的操作操作。
答案 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实现可能会更好。