我对从CSV获取数据有疑问,还是建议使用其他格式?我应该使用什么数组或字典或查找?
在我的WPF对象中,我打算有一个搜索框和一个显示搜索结果的列表框。
数据库由两列组成,例如
雪莉,好郎 乔,快乐
艾伯特,聪明的 雪莉,漂亮的 杰西卡,可爱的 乔,伟大
所以第一列是某人的名字,第二列是它的形容词。我只是举一个例子来说明。基本上我会搜索第一列,并且单个名称可能有" n"形容词的数量甚至只是1。
我可以使用字典数据格式吗?但如果是这样的话,我可以加入关键词" Shelly"如果在通过这些线路时遇到另一个值?
或者使用Lookup更好吗?
CSV文件的大小可能约为30000行,2列。当我搜索Shelly时,我希望得到Good,Pretty,我可以使用它来填充我的列表框。
谢谢!
答案 0 :(得分:0)
我会使用Dictionnary <string, List<string>>
来存储值。
在您的情况下,名称似乎是关键,可能有多个值。
当您解析CSV时,您需要检查字典是否包含Key“Shelly”,否则您创建条目&lt;“Shelly,新列表{”您实际得到的形容词“&gt;
如果存在“Shelly”键,则只需将当前形容词添加到值列表中。
答案 1 :(得分:0)
你可以使用;
IDictionary<string, IList<string>> myData = new Dictionary<string, IList<string>>();
键值保持Shelly,List将保持{Good,Pretty}
答案 2 :(得分:0)
使用以下内容存储值
Dictionary<string, List<string>> databaseData = new Dictionary<string, List<string>>();
并在下面搜索使用:
List<string> results;
databaseData.TryGetValue("Shelly", out results);
将Shelly
替换为您的搜索变量。对于上面的例子,结果将保持良好,漂亮。
答案 3 :(得分:0)
我不会使用嵌套集合。你确定你会记得下周所有这些字符串的作用吗?如何获得其中一个形容词所需的doule索引,例如dict["Lucy"][1]
?
创建一个包含该名称的名称和形容词的小类,并绑定到其实例列表。与创建嵌套结构相比,从CSV创建列表并不困难(实际上更容易)。您可以使用该名称作为字典的键,以便于查找。
您可以使用同时接受键和内容选择器的GroupBy overload将名称与形容词分开。
例如:
class Person
{
public string Name{get;set;}
public string[] Adjectives{get;set;}
}
Dictionary<string,Persons> _persons;
var lucysAdjectives = _persons["Lucy"].Adjectives;
要创建列表,您可以像创建字典一样对CSV值进行分组。假设您的CSV解析器返回Item1,Item2对象的序列,您可以写:
_persons = csvRows.GroupBy(
pair=>pair.Item1, //The key to group by
pair=>pair.Item2 //The group's contents
)
.ToDictionary(
g=>g.Key,
new Person{
Name=g.Key,
Adjectives=g.ToArray()
}
);
假设文件不包含标题,引号等,您可以只读取每一行并将其拆分。在这种情况下,您可以将文件读入_persons
字典,如下所示:
_persons = File.ReadLines(pathToFile)
.Select( line => line.Split(','))
.GroupBy( pair => pair[0],
pair => pair[1])
.ToDictionary( g => g.Key,
new Person{ Name=g.Key, Adjectives=g.ToArray()});
您可以通过向接受名称和IEnumerable<string>
的Person添加构造函数来简化代码,和/或使其不可变以防止意外修改,例如:
class Person
{
public string Name{get;}
public string[] Adjectives{get;}
Person(string Name,IEnumerable<string> adjectives)
{
Name=name;
Adjectives=adjectives.ToArray();
}
}
_persons = File.ReadLines(pathToFile)
.Select( line => line.Split(','))
.GroupBy( pair => pair[0],
pair => pair[1])
.ToDictionary( g => g.Key,
new Person(g.Key, g));
或从组中创建Person对象,然后从Persons
创建一个字典_persons = File.ReadLines(pathToFile)
.Select( line => line.Split(','))
.GroupBy( pair => pair[0],
pair => pair[1])
.Select( g => new Person(g.Key, g))
.ToDictionary( person => person.Name,
person => person);
<强>更新强>
如果你不想创建小类(为什么?)并且字典的范围很小,例如单个方法,你可以使用C#7的元组。
var persons = File.ReadLines(pathToFile)
.Select( line => line.Split(','))
.GroupBy( pair => pair[0],
pair => pair[1])
.Select( g => (Name=g.Key, Adjectives=g.ToArray()))
.ToDictionary( person => person.Name,
person => person);
范围必须很小,因为元组名称只是编译器魔术。这些字段实际上名为Item1,Item2等。编译器魔术允许您按名称引用它们。
您也无法定义元组类型或别名,这意味着您必须在返回类型,字段声明等中重复元组定义:
Dictionary<string,(string Name,string[] Adjectives)> _persons ;
代码变得非常丑陋