我有一个字典Dictionary<string, List<string>>
,我想按字母顺序按键排序,并将其转换为一个字符串,可以写入CSV文件,键作为列标题,值作为该列的值。
我的onordered字典看起来像:
{
"Name" : ["John", "Ciara", "Moses"],
"Age" : ["23", "16", "37"],
"State" : ["Alabama", "Florida", "New York"]
}
最终结果如下:
Age,Name,State
23,John,Alabama
16,Ciara,Florida
37,Moses,New York
请问我如何在c#中实现这一点?
为清楚起见,这里有一个任务需要的链接。
下面是我解它的方法。我将字符串转换为字典,以列标题作为键。我现在的问题是将字典转换回字符串格式。
public static string SortCsvColumns( string csv_data )
{
var data = csv_data.Split(new string[] { Environment.NewLine }, StringSplitOptions.None);
var values = data.Skip(1).ToArray();
var splittedValues = new List<List<string>>();
var dataSet = data[0].Split(new string[] {","}, StringSplitOptions.None).ToDictionary(x => x, x => new List<string>());
for(int i = 0; i < values.Length; i++)
{
splittedValues.Add(values[i].Split(new string[] { "," }, StringSplitOptions.None).ToList());
}
for(int i = 0; i < splittedValues.Count(); i++) {
var splittedValue = splittedValues[i];
for(int j = 0; j < splittedValue.Count(); j++) {
dataSet.Values.ElementAt(i).Add(splittedValue[j]);
}
}
dataSet = dataSet.OrderBy(key => key.Key);
}
谁能建议最好的方法来做这件事?
首先,创建一个映射,按照列标头的排序顺序对列进行重新排序:
var map = new StringReader(csv_data).ReadLine() // get header line
.Split(';') // split into array of headers
.Select((h, n) => new { header = h, OrigPos = n }) // remember original position
.OrderBy(hn => hn.header, StringComparer.CurrentCultureIgnoreCase) // sort into new position
.Select(hn => hn.OrigPos) // return just old position new new order
.ToList();
然后将每个CSV行重新映射到新的顺序,并重新组合成一个string
:
using var sr = new StringReader(csv_data);
var ans = String.Join("n",
sr.ReadLines()
.Select(line => line.Split(';'))
.Select(columns => String.Join(";", map.Select(pos => columns[pos]))));
这需要TextReader
上的扩展方法来枚举TextReader
的行:
public static class StringReaderExt {
public static IEnumerable<string> ReadLines(this TextReader sr) {
string line;
while ((line = sr.ReadLine()) != null)
yield return line;
}
}