如果标题令人困惑,我很抱歉,我并不确定如何标记这一点,我试过了。
我正在编写一个程序来进行跨索引搜索,该程序是使用Visual Studio 2010用C#编写的。
我有一个包含3列的表格:Category
,Type
和Item
。该表从excel电子表格中读入并存储在某种数据结构中(稍后将对此进行说明)。以下是该表的简短示例。
| CATEGORY | TYPE | ITEM | <<header row
| categoryA | typeA | itemA | <<first entry
| categoryA | typeB | N/A |
| categoryA | typeC | itemB |
| categoryA | typeD | N/A |
我将读取两个用户输入字符串,我希望程序确定它们是否匹配。 [假设用户输入没有拼写错误,我编写了一个函数来处理这个并规范化两个字符串]
确定两个字符串是否匹配的逻辑如下:
1)如果字符串是CATEGORY
,则具有相同TYPE
的每个ITEM
和CATEGORY
都匹配。
2)如果字符串是TYPE
或ITEM
,则只有同一行中的其他数据匹配
以下是一些示例,字符串a和b是两个输入字符串,match是布尔值:
1) a = "categoryA", b = "typeA", match = true
2) a = "categoryA", b = "itemB", match = true
3) a = "typeC", b = "itemB", match = true
4) a = "typeC", b = "itemA", match = false
5) a = "itemA", b = "itemB", match = false
如果不够清楚,我会举出更多例子。
所以我的整体问题是:从excel电子表格中存储数据的最合适的数据结构是什么,以及如何与此数据结构进行搜索/比较匹配?
我虽然使用Dictionary<string, string>
,所以我可以在字典中搜索字符串a并获取匹配字符串列表并进行比较,但这样我会有一个庞大的字典和多个相同的键,这不会工作
感谢任何建议/帮助。
答案 0 :(得分:2)
我会考虑使用System.Data
命名空间中的DataTable,它适合存储在内存表格数据中。什么可能使你更有吸引力是可以通过DataView类RowFilter属性查询SQL,如查询。
一些伪代码:
DataTable excelTable = new DataTable();
//a method that reads Excel doc and injects data into DataTable
PopulateFromExcel(excelTable);
DataView dv = new DataView(excelTable);
dv.RowFilter = "a = 'categoryA' AND b= 'typeA'";
var match = dv.Count > 0;
答案 1 :(得分:1)
我有两个建议:一个优化效率,而另一个优化内存使用:
如果进行大量查找,最有效的数据结构可能是元组的HashSet 。这是一个例子:
var set = new HashSet<Tuple<string, string>>();
set.Add(Tuple.Create("categoryA", "typeA"));
set.Add(Tuple.Create("categoryA", "itemA"));
set.Add(Tuple.Create("typeA", "itemA"));
set.Add(Tuple.Create("categoryA", "typeB"));
set.Add(Tuple.Create("categoryA", "typeC"));
set.Add(Tuple.Create("categoryA", "itemB"));
...
var found1 = set.Contains(Tuple.Create("categoryA", "typeC")); // yields True
var found2 = set.Contains(Tuple.Create("itemA", "itemB")); // yields False
当您读取数据时,为每行添加所有可能为HashSet产生True的组合。它会很大,但查找操作应该几乎是即时的。
或者,您可以使用字段MyRow
,Category
和Type
创建一个类Item
,并将数据存储在List<MyRow>
中。然后,您可以使用LINQ查找匹配的记录:
var isMatch = myList.Any(row => (row.Category == string1 && row.Type == string2)
|| (row.Category == string1 && row.Item == string2)
|| ...);
这需要最少的内存(因为每个值只存储一次)。但是,每个搜索操作都会遍历完整列表,直到找到匹配项。
答案 2 :(得分:0)
我建议使用DOCMD.TransferSpreadsheet方法并导出excel数据以进行访问并执行一些简单的查询以符合您的要求。