c# - 使用 csvHelper 将单元格内容读入列表或数组
问题描述
我有一个类型的 csv 文件:
name,numbersA,numbersB
Bob,"1,2,3,4","6,7,8,9"
Brabra,"9,3","4,8,5,7,2"
所以整数数组由“”之间的数字给出。
我想将其映射到以下课程
public class Names
{
[Name("name")]
public string Name { get; set; }
[Name("numbersA")]
public List<int> NumbersA{ get; set; }
[Name("numbersB")]
public List<int> NumbersB{ get; set; }
}
我并不特别介意 NumbersA/B 的类型是 int[] 还是 List。到目前为止,我设法通过将 NumbersA/B 的类型指定为字符串来读取数据,并且工作正常(我得到了“”之间的字符串)。这可以在 csvHelper 中自动完成,还是我以后必须自己解析字符串。
void Main()
{
using (var reader = new StreamReader("path\\to\\file.csv"))
using (var csv = new CsvReader(reader, CultureInfo.InvariantCulture))
{
var records = csv.GetRecords<Names>();
List<Names> NameList = records.ToList();
}
}
任何帮助将不胜感激。
解决方案
归功于@Oguz Ozgul(见下文)。我做了一些小的改动。
public class Names
{
[Name("name")]
public string Name { get; set; }
[Name("numbersA")]
[TypeConverter(typeof(ToIntArrayConverter))]
public List<int> NumbersA{ get; set; }
[Name("numbersB")]
[TypeConverter(typeof(ToIntArrayConverter))]
public List<int> NumbersB{ get; set; }
}
public class ToIntArrayConverter : TypeConverter
{
public override object ConvertFromString(string text, IReaderRow row, MemberMapData memberMapData)
{
if (text == "") return new List<int>();
string[] allElements = text.Split(',');
int[] elementsAsInteger = allElements.Select(s => int.Parse(s)).ToArray();
return new List<int>(elementsAsInteger);
}
public override string ConvertToString(object value, IWriterRow row, MemberMapData memberMapData)
{
return string.Join(",", ((List<int>)value).ToArray());
}
}
解决方案
您可以实现自定义类型转换器并在转换期间(双向)为您的两个属性使用它。
该类TypeConverter
在命名空间下CsvHelper.TypeConversion
在TypeConverterAttribute
命名空间下CsvHelper.Configuration.Attributes
public class ToIntArrayConverter : TypeConverter
{
public override object ConvertFromString(string text, IReaderRow row, MemberMapData memberMapData)
{
string[] allElements = text.Split(',');
int[] elementsAsInteger = allElements.Select(s => int.Parse(s)).ToArray();
return new List<int>(elementsAsInteger);
}
public override string ConvertToString(object value, IWriterRow row, MemberMapData memberMapData)
{
return string.Join(',', ((List<int>)value).ToArray());
}
}
TypeConverterAttribute
要使用此转换器,只需在属性顶部添加以下注释:
public class Names
{
[Name("name")]
public string Name { get; set; }
[Name("numbersA")]
[TypeConverter(typeof(ToIntArrayConverter))]
public List<int> NumbersA { get; set; }
[Name("numbersB")]
[TypeConverter(typeof(ToIntArrayConverter))]
public List<int> NumbersB { get; set; }
}
推荐阅读
- angular - 无法从角度连接 laravel 网络套接字
- codeigniter - 我为 foreach 提供的应用程序无效参数有问题
- php - 无法使用 php 在 chrome 中显示从外部 url 加载的 pdf 文件
- selenium - 如何为 Mat-Icons 使用 Click Button 关键字?
- scala - 连接到通配符 ip 0.0.0.0 在容器中有效,但在主机上无效
- laravel - 有没有办法通过点击内联键盘向电报机器人发送消息?
- node.js - 使用 Promisify 时找不到属性“svc”
- ios - react-navigation 正在 iOS 模拟器上工作,但在 iOS 真实设备上面临导航问题
- javascript - 条件运算符在 javascript 中无法按预期工作
- c# - Building truly dynamic queries