将csvhelper列表转换为字典

huangapple go评论78阅读模式
英文:

converting csvhelper list into a dictionary<string, object>

问题

我有一个看起来像这样的CSV文件:

23.75,-71.14026637566099,23.26,-68.14,X (mm),Y (mm),X (mm),Y (mm),X (mm),Y (mm)
...

获取这个数据对我来说不是问题,这是我的工作代码:

class CsvHelperTester
{
    ...
}

我想将这个列表转换成一个字典,类似于List<Dictionary<string,object>>。因此,数据需要转换成水平数据,像这样:

Y(mm) : -61.232543
Y2(mm) : 63.23532

然而,我不确定如何进行这种类型的转换,或者是否有更好的解决方案。我无法控制这个CSV,所以它会按照这种方式传递给我。我甚至不知道数据是否可以转换成我需要的字典。我需要将数据转换成这种格式,因为我打算将这些数据转换成一个DataTable并发送到MongoDB,以便可以很好地读取它。任何帮助将不胜感激,谢谢!

英文:

I have a csv file that looks like this:

23.75,-71.14026637566099,23.26,-68.14,X (mm),Y (mm),X (mm),Y (mm),X (mm),Y (mm)
75.0,0.0,72.0,0.0,-70.8744,-11.0272,-62.1812,-22.0121,1.1013,5.3621
74.62531239585194,7.487506248512112,71.64029990001787,7.188005998571628,-66.1987,26.7792,-61.3198,24.1895,5.8892,34.9479
73.50499333809312,14.90019980962959,70.5647936045694,14.304191817244408,-54.6861,21.1036,-60.9723,-29.1698,,
71.65023668442045,22.16401549960047,68.78422721704364,21.27745487961645,-53.3795,20.8321,-57.5484,-7.0754,,
69.07957455021638,29.206375673148788,66.31639156820773,28.038120646222836,-44.5103,16.9127,-50.7663,34.2947,,
65.81869214177796,35.95691539531523,63.18594445610684,34.518638779502616,,,-48.7116,52.8106,,
61.90017111822588,42.34818550462765,59.42416427349683,40.65425808444255,,,-39.5089,41.8543,,
57.363164046336635,48.31632654282683,55.06863748448316,46.38367348111376,,,-38.6843,-45.1223,,
52.253003201037416,53.8017068174642,50.16288307299591,51.649638544765644,,,-37.7029,40.9664,,
46.62074762029984,58.74951822206125,44.75591771548784,56.399537493178805,,,-36.1945,7.7452,,
40.52267294011048,63.11032386059223,38.90176602250607,60.58591090616855,,,-33.1654,-12.0199,,
34.01970910691831,66.84055200460764,32.65892074264157,64.16692992442336,,,-27.4216,65.4545,,
27.17683158575052,69.90293144754197,26.089758322320485,67.1068141896403,,,-26.9546,-27.5354,,
20.06241214684405,72.26686390628947,19.25991566097029,69.37618935003789,,,-25.4676,24.2481,,
12.747535717518062,73.90872974913452,12.237634288817338,70.95238055916914,,,-19.3518,-53.9162,,
5.305290125077701,74.81212399530408,5.093078520074609,71.81963903549192,,,-15.8018,36.0254,,
-2.1899641725966776,74.96802022811288,-2.102365605692795,71.96929941898837,,,-12.8175,26.027,,
-9.663337072164381,74.37486078393515,-9.27680358927779,71.39986635257773,,,-12.8157,33.5647,,
-17.040157101981563,73.03857231586463,-16.358550817902273,70.11702942323005,,,-12.6135,14.0177,,
-24.246717514762796,70.97250657655607,-23.276848814172258,68.13360631349384,,,-12.5522,44.1962,,
-31.21101274103571,68.19730701192611,-29.962572231394255,65.46941473144908,,,-11.0237,4.4988,,
-37.86345784498934,64.74070249866551,-36.34891953118974,62.151074398718904,,,-11.014,15.0086,,

Getting this data is not a problem for me, here is my working code.

 class CsvHelperTester
    {
        static void Main(string[] args)
        {
            var config = new CsvConfiguration(CultureInfo.InvariantCulture)
            {
                HasHeaderRecord = false,
                MissingFieldFound = null,
                ShouldSkipRecord = args =&gt; args.Row.Parser.Record.All(String.IsNullOrEmpty)
            };

            using (var reader = new StreamReader(&quot;C:\\Users\\eyoung\\Desktop\\parse test files\\Data.csv&quot;))
            using (var csv = new CsvReader(reader, config))
            {
                var SicaGraphData = new List&lt;SicaGraphData&gt;();

                while (csv.Read())
                {
                    SicaGraphData.Add(csv.GetRecord&lt;SicaGraphData&gt;());
                }

            }
        }

        public class SicaGraphData
        {
            public string Value1 { get; set; }
            public string Value2 { get; set; }
            public string Value3 { get; set; }
            public string Value4 { get; set; }
            [Name(&quot;X (mm)&quot;)]
            public string X { get; set; }
            [Name(&quot;Y (mm)&quot;)]
            public string Y { get; set; }
            [Name(&quot;X2 (mm)&quot;)]
            public string X2 { get; set; }
            [Name(&quot;Y2 (mm)&quot;)]
            public string Y2 { get; set; }
            [Name(&quot;X3 (mm)&quot;)]
            public string X3 { get; set; }
            [Name(&quot;Y3 (mm)&quot;)]
            public string Y3 { get; set; }
        }
        
    }

What I want to do is convert this lost list into a dictionary, like List<Dictionary<string,object>> So the data needs to be converted into horizontal data, like this:

Y(mm) : -61.232543
Y2(mm) : 63.23532

However, I'm not sure how to do this type of conversion or if there is a better solution. I have no control over this csv, so this is just how it will come to me. I don't even know if the data can be converted into the dictionary that I need. I need the data converted into this format, as I'm going to convert this data into a datatable and send it to MongoDB, so it can be read nicely. Any help would be greatly appreciated, thanks!

答案1

得分: 1

这可以通过反射来实现。只是指出反射比从 SicaGraphData 类写出转换为字典的方式要慢,但认为这是一个展示它如何工作的好用例。

代码只是一个示例,使用反射来检查属性和值可能在创建复杂类或使用泛型时会有些棘手。

我创建了两种方法。第一种是根据问题将数据转换为输出的方法。这种方法实际上不需要反射,你可以轻松编写一个方法将行映射到字典。
这是一个简单的映射/选择函数。

public static List<Dictionary<string, object?>> PivotRecord(List<SicaGraphData> data){
    return data.Select(row => MapToDictionary(row)).ToList();
}

private static Dictionary<string, object?> MapToDictionary(SicaGraphData row) {
    var dictionary = new Dictionary<string, object?>(){};
    foreach(var prop in row.GetType().GetProperties()) {
        var cellValue = prop.GetValue(row, null);
        dictionary.Add(prop.Name, cellValue);
    }
    return dictionary;
}

第二种方式将数据转换为带有值列表的字典。这可以看作是一个"Reduce"函数。

public static Dictionary<string, List<object?>> PivotDataSet(List<SicaGraphData> data){
    var dictionary = new Dictionary<string, List<object?>>();
    var properties = typeof(SicaGraphData).GetProperties();
    foreach(var row in data) {
        foreach(var prop in properties) {
            var cellValue = prop.GetValue(row, null);
            if (dictionary.TryGetValue(prop.Name, out var list)) {
                list.Add(cellValue);
            } else {
                dictionary.Add(prop.Name, new List<object?>(){ cellValue});
            }
        }
    }
    return dictionary;
}
英文:

This could be done using reflection. Just stating that reflection will be slower than writing out the conversion from the SicaGraphData class to a dictionary but thought this is a good use case for show casing how it works.

The code is just an example, checking properties and values using reflection can be a little bit trickier if you create complex classes or using generics.

I've created two approaches. The first to convert the data into the output based on the question. This approach really doesn't need reflection, you can easily write a method to map a row to a dictionary.
This is a simple map/select function.

        public static List&lt;Dictionary&lt;string, object?&gt;&gt; PivotRecord(List&lt;SicaGraphData&gt; data){
            return data.Select(row =&gt; MapToDictionary(row)).ToList();
        }

         private static Dictionary&lt;string, object?&gt; MapToDictionary(SicaGraphData row) {
            var dictionary = new Dictionary&lt;string, object?&gt;(){};
            foreach(var prop in row.GetType().GetProperties()) {
                var cellValue = prop.GetValue(row, null);
                dictionary.Add(prop.Name, cellValue);
            }
            return dictionary;
        }

The second variance converting the data into a dictionary with a list of values. This can be seen as a Reduce function.

        public static Dictionary&lt;string, List&lt;object?&gt;&gt; PivotDataSet(List&lt;SicaGraphData&gt; data){
            var dictionary = new Dictionary&lt;string, List&lt;object?&gt;&gt;();
            var properties = typeof(SicaGraphData).GetProperties();
            foreach(var row in data) {
                foreach(var prop in properties) {
                    var cellValue = prop.GetValue(row, null);
                    if (dictionary.TryGetValue(prop.Name, out var list)) {
                        list.Add(cellValue);
                    } else {
                        dictionary.Add(prop.Name, new List&lt;object?&gt;(){ cellValue});
                    }
                }
            }
            return dictionary;
        }

huangapple
  • 本文由 发表于 2023年6月14日 23:53:53
  • 转载请务必保留本文链接:https://go.coder-hub.com/76475433.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定