C#将字符串拆分为数组,然后将字符串中的键值对拆分

时间:2018-03-01 20:53:55

标签: c# arrays dictionary

我目前正在将一个带有多个分隔符的字符串传递给我想要最初拆分(at~)到字符串数组的方法,然后将数组中的每个条目(at |)传递给字典( "键" ="值"。)

~timestamp=Mar  1 2018  3:14PM|proc=procedure A|tran=transaction 1|rowCount=987
~timestamp=Mar  1 2018  3:14PM|proc=procedure B|tran=transaction 2|rowCount=654
~timestamp=Mar  1 2018  3:14PM|proc=procedure C|tran=transaction 3|rowCount=321

我可以完成初步拆分为个别"行"

~timestamp=Mar 1 2018 3:14PM|proc=procedure A|tran=transaction 1|rowCount=987

使用:

string result = <<long string>>;
string filepath = <<filepath variable>>;
string[] resultRows = result.Split('~');

try
{
    foreach (string row in resultRows)
    {
        if (!File.Exists(filepath))
        {
            using (StreamWriter log = File.CreateText(filepath))
            {
                log.WriteLine(row);
            }
        }
        else
        {
            using (StreamWriter log = File.AppendText(filepath))
            {
                log.WriteLine(row);
            }
        }
    }
}
catch (Exception e)
{
    Console.WriteLine(e.Message);
}

然而,当我尝试解析每个&#34;行&#34;在一个字典中,抛出一个错误(索引超出了数组的范围)。

string result = <<long string>>;
string filepath = <<filepath variable>>;
string[] resultRows = result.Split('~');
Dictionary<string, string> dict = new Dictionary<string, string>();

try
{
    foreach (string row in resultRows)
    {
        var results = row.Split('|').Select(s => s.Split(new[] { '=' }));

        foreach (var item in results)
        {
            dict.Add(item[0], item[1]);
        }
    }
}
catch (Exception e)
{
    Console.WriteLine(e.Message);
}

我假设我对字典的期望是不正确的 - 我希望看到以下内容,对于每个&#34;条目&#34;在词典中:

~timestamp=>Mar 1 2018 3:14PM, proc=>procedureA, tran=>transaction1, rowCount=>987

这样我就可以将每一行写入日志文件,在那里我可以单独访问每个键的值。如果我对如何在字典中设置/获取值的理解有所了解,是否有更好的方法来完成此任务?

3 个答案:

答案 0 :(得分:2)

主要问题是可能是空的拆分部分,并且在进一步拆分后尝试通过dict.Add(item[0], item[1]);中的索引访问它们 - 如果只有一个结果,则其索引超出范围异常。

在您的拆分~数组中使用IEnumerable.Aggregate()的固定版本:

using System;
using System.Collections.Generic;
using System.Linq;

public class Program
{
    public static void Main(string[] args)
    {
        var dd = new Dictionary<string, Dictionary<string, string>>();
        var data = 
        "~timestamp=Mar 1 2018 3:14PM|proc=procedure A|tran=transaction 1|rowCount=987" +
        "~timestamp=Mar 1 2018 3:14PM|proc=procedure B|tran=transaction 2|rowCount=654" +
        "~timestamp=Mar 1 2018 3:14PM|proc=procedure C|tran=transaction 3|rowCount=321";


        // splitting is done here:

        var d = data  
            .Split(new[] { '~' }, StringSplitOptions.RemoveEmptyEntries) 
            .Aggregate(new List<Dictionary<string, string>>(), 
            (listOfDicts, part) =>
            {
                var key = Guid.NewGuid().GetHashCode().ToString();
                listOfDicts.Add(new Dictionary<string, string>());

                foreach (var p in part.Split(new[] { '|' },
                                             StringSplitOptions.RemoveEmptyEntries))
                {
                    // limit split to 2 parts if more then 1 = inside
                    var kvp = p.Split(new[] { '=' }, 2,
                                      StringSplitOptions.RemoveEmptyEntries);

                    // either 2 or 1 is the result, handle both:
                    if (kvp.Count() == 2)
                        listOfDicts.Last()[kvp[0]] = kvp[1];
                    else
                        listOfDicts.Last()[kvp[0]] = null;
                }
                return listOfDicts;
            });


        // output:

        foreach (var k in d)
        {
            Console.WriteLine();
            foreach (var innerKvp in k)
            {
                Console.WriteLine("    " + innerKvp.Key + "    " + innerKvp.Value);
            }
        }
        Console.ReadLine();
    }
}

输出:(词典列表)

timestamp    Mar 1 2018 3:14PM
proc    procedure A
tran    transaction 1
rowCount    987

timestamp    Mar 1 2018 3:14PM
proc    procedure B
tran    transaction 2
rowCount    654

timestamp    Mar 1 2018 3:14PM
proc    procedure C
tran    transaction 3
rowCount    321

答案 1 :(得分:2)

以下功能应该能够正确解析您的输入:

private static List<Dictionary<String,String>> ParseData(String data)  
{
    String[] entriesData = data.Split(new Char[] { '~' },StringSplitOptions.RemoveEmptyEntries);
    List<Dictionary<String,String>> result = new List<Dictionary<String,String>>(entriesData.Length);

    foreach (String entryData in entriesData)
    {
        String[] entryDataPairs = entryData.Split(new Char[] { '|' },StringSplitOptions.RemoveEmptyEntries);
        Dictionary<String,String> entryResult = new Dictionary<String,String>(entryDataPairs.Length);

        foreach (String entryDataPair in entryDataPairs)
        {
            String[] kvp = entryDataPair.Split(new Char[] { '=' },StringSplitOptions.RemoveEmptyEntries);
            entryResult.Add(kvp[0], kvp[1]);
        }

        result.Add(entryResult);
    }

    return result;
}

以下输入字符串产生的结果:

~timestamp=Mar  1 2018  3:14PM|proc=procedure A|tran=transaction 1|rowCount=987~timestamp=Mar  1 2018  3:14PM|proc=procedure B|tran=transaction 2|rowCount=654~timestamp=Mar  1 2018  3:14PM|proc=procedure C|tran=transaction 3|rowCount=321

是:

--- ENTRY ---
timestamp = Mar  1 2018  3:14PM
proc = procedure A
tran = transaction 1
rowCount = 987

--- ENTRY ---
timestamp = Mar  1 2018  3:14PM
proc = procedure B
tran = transaction 2
rowCount = 654

--- ENTRY ---
timestamp = Mar  1 2018  3:14PM
proc = procedure C
tran = transaction 3
rowCount = 321

访问this link尝试试试!

答案 2 :(得分:0)

尝试这样的事情:

var dictionary = new Dictionary<string, string>();

foreach (var resultRow in resultRows)
{
    if(!string.IsNullorEmpty(resultRow))
    {
        var rowItems = resultRow.Split('|').ToList();

        dictionary.Add(rowItems.First(), string.Join("|", rowItems.Skip(1));
    }
}