【发布时间】:2020-02-07 14:33:34
【问题描述】:
(我正在使用 CSVHelper 包)
你好,
我有一个 sbyte[] 数组,它保存 CSV 文件中每个标题列的位置。数组定义如下,
public sbyte[] ColumnIndex = new sbyte[Enum.GetNames(typeof(MyEnum)).Length];
并说我有一个如下所示的 CSV 文件:
col1,col2,col3,col4
name1,empId1,241682-27638-USD-CIGGNT ,1
name2,empId2,241682-27638-USD-OCGGINT ,1
name3,empId3,241942-37190-USD-GGDIV ,2
name4,empId4,241942-37190-USD-CHYOF ,1
name5,empId5,241942-37190-USD-EQPL ,1
name6,empId6,241942-37190-USD-INT ,1
name7,empId7,242066-15343-USD-CYJOF ,3
name8,empId8,242066-15343-USD-CYJOF ,3
name9,empId9,242066-15343-USD-CYJOF ,3
name10,empId10,241942-37190-USD-GGDIV ,2
现在调用字节数组并传递Enum 索引将返回标题行中的位置:
int conversion = (int)MyEnum.col3;
ColumnIndex[conversion]);
returns 2
现在这一切正常,但我似乎很难弄清楚如何根据我拥有的位置索引将每列与其信息映射到分隔 List<string>。
我尝试使用以下代码将所有字段放在一个 List<string> 中:
public List<string> ParseEntire(aliasType type, string PathToFile) {
List<string> result = new List<string>();
using (TextReader fileReader = File.OpenText(PathToFile)) {
var csv = new CsvReader(fileReader, CultureInfo.InvariantCulture);
string value;
while (csv.Read()) {
for (int i = 0; csv.TryGetField<string>(i, out value); i++) {
result.Add(value);
}
}
}
return result;
}
但是,这没有用,因为我无法知道每个标题的位置。我觉得使用CSVHelper 包有一种更简单的方法,我只是让一个简单的任务复杂化。任何帮助将不胜感激。
编辑: 对于下面的Emun
public enum aliasType {
col5,
col4,
col3,
col2,
col1
}
执行代码将位置索引映射到ColumnIndex 后,它看起来像这样:
ColumnIndex {sbyte[4]}
[0] [-1]
[1] [3]
[2] [2]
[3] [1]
[4] [0]
我这样做主要是因为我不知道标题行包含什么。因此,我尽可能多地提取信息,当我返回 -1 的索引时,我知道该特定字段不存在。
更新:
以下代码使用Intersect 与我尝试提取的同一标题列的不同别名进行比较。
public List<string> HeaderColumnParser(aliasType type, string PathToFile) {
List<string> result = new List<string>();
using (TextReader fileReader = File.OpenText(PathToFile)) {
var csv = new CsvReader(fileReader, CultureInfo.InvariantCulture);
CSVBOM extract = new CSVBOM("", CSVBOM.BOMFileType.csv);
csv.Read();
csv.ReadHeader();
string[] header = csv.Context.HeaderRecord;
IEnumerable<string> CommonHeaders;
foreach (aliasType foo in Enum.GetValues(typeof(aliasType))) {
int res = Convert.ToInt32(foo);
switch (res) {
case 0:
// get matching string
CommonHeaders = header.Intersect(ReferenceDesignatorAliases);
ColumnIndex[res] = extract.ExtractIndexHeader(CommonHeaders, header);
break;
case 1:
CommonHeaders = header.Intersect(ManufacturersPartNumberAliases);
ColumnIndex[res] = extract.ExtractIndexHeader(CommonHeaders, header);
break;
case 2:
CommonHeaders = header.Intersect(ValueAliases);
ColumnIndex[res] = extract.ExtractIndexHeader(CommonHeaders, header);
break;
case 3:
CommonHeaders = header.Intersect(DescriptionShortAliases);
ColumnIndex[res] = extract.ExtractIndexHeader(CommonHeaders, header);
break;
case 4:
CommonHeaders = header.Intersect(DescriptionLongAliases);
ColumnIndex[res] = extract.ExtractIndexHeader(CommonHeaders, header);
break;
case 5:
CommonHeaders = header.Intersect(ManufacturerAliases);
ColumnIndex[res] = extract.ExtractIndexHeader(CommonHeaders, header);
break;
case 6:
CommonHeaders = header.Intersect(DNIAliases);
ColumnIndex[res] = extract.ExtractIndexHeader(CommonHeaders, header);
break;
case 7:
CommonHeaders = header.Intersect(DataSheetAliases);
ColumnIndex[res] = extract.ExtractIndexHeader(CommonHeaders, header);
break;
default:
throw new Exception("Alias type is not recognized");
}
}
}
return result;
}
我的枚举和别名字符串数组:
public enum aliasType {
ReferenceDesignatorAliases,
ManufacturersPartNumberAliases,
ValueAliases,
DescriptionShortAliases,
DescriptionLongAliases,
ManufacturerAliases,
DNIAliases,
DataSheetAliases
}
//Returns -1 meaning not found
public sbyte[] ColumnIndex = new sbyte[Enum.GetNames(typeof(aliasType)).Length];
public string[] ReferenceDesignatorAliases = { "Reference Designator", "RefDes", "Designator", "Annotation" };
public string[] ManufacturersPartNumberAliases = { "Manufacturer's Part Number", "MPN", "PN", "part Number" };
public string[] ValueAliases = { "Value" };
public string[] DescriptionShortAliases = { "Description Short", "Description" };
public string[] DescriptionLongAliases = { "Description Long" };
public string[] ManufacturerAliases = { "Manufacturer", "MF" };
public string[] DNIAliases = { "DNI", "Do Not Install" };
public string[] DataSheetAliases = { "DataSheet", "Data Sheet" };
【问题讨论】:
-
我不确定我是否理解。
ColumnIndex的列顺序是否与 CSV 文件不同? -
我的方法是,在我传入标题列的 Enum 值后,我想要该位置并返回该位置。我将编辑我的答案以进一步解释这一点
标签: c# csv dictionary csvhelper