交叉索引引用

对不起,如果标题令人困惑,我不确定我应该如何标记这个,我试过了。

我正在编写一个程序来进行一些交叉索引搜索,该程序是使用Visual Studio 2010用C#编写的。

我有一个包含3列的表: CategoryTypeItem 。 该表从excel电子表格中读入并存储在某种数据结构中(稍后将对此进行说明)。 以下是该表的简短示例。

 | CATEGORY | TYPE | ITEM | <<header row | categoryA | typeA | itemA | <<first entry | categoryA | typeB | N/A | | categoryA | typeC | itemB | | categoryA | typeD | N/A | 

我将读取两个用户输入字符串,我希望程序确定它们是否匹配。 [假设用户输入没有拼写错误,我写了一个函数来处理这个并规范化两个字符串]

确定两个字符串是否匹配的逻辑如下:

1)如果字符串是CATEGORY ,则具有相同CATEGORY每个TYPEITEM都是匹配的。

2)如果字符串是TYPEITEM ,则只有同一行中的其他数据匹配

以下是一些示例,字符串a和b是两个输入字符串,匹配是一个布尔值:

 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 ,所以我可以在字典中搜索字符串a并获得匹配字符串列表并进行比较,但这样我将拥有一个庞大的字典和多个相同的密钥,这将无法工作。

任何建议/帮助表示赞赏。

我会考虑使用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; 

我有两个建议:一个优化效率 ,另一个优化内存使用


如果进行大量查找,最有效的数据结构可能是元组HashSet 。 这是一个例子:

 var set = new HashSet>(); 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其中包含CategoryTypeItem字段,并将数据存储在List 。 然后,您可以使用LINQ查找匹配的记录:

 var isMatch = myList.Any(row => (row.Category == string1 && row.Type == string2) || (row.Category == string1 && row.Item == string2) || ...); 

这需要最少的内存(因为每个值只存储一次)。 但是,每个搜索操作都会遍历完整列表,直到找到匹配项。

我建议使用DOCMD.TransferSpreadsheet方法并导出excel数据以进行访问并执行一些简单的查询以满足您的要求。