繁体   English   中英

CSV在字典中附加特定的字符串

[英]CSV appending specific strings in Dictionary

我希望将两个CSV文件合并为1个文件。

CSV

WBS Element,Purchasing Document,Purchase order text,Val/COArea Crcy
ABC123,,,75000
ABC124,4200028630,Service,1069.2
ABC124,4200041490,Service,25518.24
ABC124,4200041490,Service,-1890.24
ABC126,4200028630,Service,2268
ABC126,4200028630,Service,-2268
ABC126,4200029435,Service,25149.65
ABC137,,,4146.2

CSV文件

WBS Element,Ref Document Number,Val/COArea Crcy,Name
ABC124,1000060610,0,Slab Locates & Steel Differential
ABC124,1000081223,0,NOCN339A&3921
ABC124,1000081223,0,Slab Locates & Steel Differential
ABC126,1000067757,0,Structural Steel
ABC 137,4200041490,0,Service
ABC 137,4200028630,5393.52,Service
ABC 137,4200029435,0,Service

我想制作1个CSV文件,将两者结合起来。 以WBS Element开头的线连接在一起。 然后将每个文件中的WBS元素匹配时放在同一行。 如果A具有WBS元素,则B没有,则B的部分仅为“,”,反之亦然。

目标输出样本:

WBS Element,Purchasing Document,Purchase order text,Val/COArea Crcy,WBS Element,Ref Document Number,Val/COArea Crcy,Name
ABC123,,,75000,,,,
ABC124,4200028630,Service,1069.2,ABC124,1000060610,0,Slab Locates & Steel Differential

我有以下代码:

static void Main(string[] args)
    {
        StreamReader a = new StreamReader(@"Input\a.csv");
        StreamReader b = new StreamReader(@"Input\b.csv");
        StreamWriter output = new StreamWriter(@"Output\output.csv");
        Dictionary<string, string> Adict = new Dictionary<string, string>();
        Dictionary<string, string> Bdict = new Dictionary<string, string>();


        output.WriteLine(a.ReadLine() + "," + b.ReadLine());

        while (!a.EndOfStream && !b.EndOfStream)
        {
            //section for A
            List<string> atempList = new List<string>();
            string atempString;
            string Aline = a.ReadLine();
            string[] Atokens = Aline.Split(','); //split the line into array
            foreach (string s in Atokens)
                atempList.Add(s); //add each string in token array to tempList
            atempList.Remove(Atokens[0]); //remove Dict Key from tempList

            StringBuilder d = new StringBuilder();

            if (!Adict.ContainsKey(Atokens[0]))
            {
                foreach (string s in atempList)
                    d.Append(s + ","); //rejoin tempList into a string with ","
                d.Append("\n"); //add a linebreak to end of templist string
                Adict.Add(Atokens[0], d.ToString()); //Add line to dictionary with Key
            }
            else  //Adict does contain key... need to remove Key and add bigger string
            {
                List<string> removeKey = new List<string>(); //temporary list

                foreach (string s in Atokens)
                    removeKey.Add(s); //create a new list from the token array
                removeKey.Remove(Atokens[0]); //remove the key from the removeKey list

                atempString = Adict[Atokens[0]];  //temporary string is what's already in dictionary
                Adict.Remove(Atokens[0]); //remove the Key + Value from dictionary.
                Adict.Add(Atokens[0], d.Append(atempString + Aline + "\n").ToString());     // string.Concat(tempString, ",", line));
            }

            //section for B
            List<string> btempList = new List<string>();
            string btempString;
            string Bline = b.ReadLine();
            string[] Btokens = Bline.Split(',');
            foreach (string s in Btokens)
                btempList.Add(s);
            btempList.Remove(Btokens[0]);

            StringBuilder f = new StringBuilder();

            if (!Bdict.ContainsKey(Btokens[0]))
            {
                foreach (string s in btempList)
                    f.Append(s + ",");
                f.Append("\n");
                Bdict.Add(Btokens[0], f.ToString());
            }
            else
            {
                List<string> removeKey = new List<string>();

                foreach (string s in Btokens)
                    removeKey.Add(s);
                removeKey.Remove(Atokens[0]);

                btempString = Bdict[Btokens[0]];
                Bdict.Remove(Btokens[0]);
                Bdict.Add(Btokens[0], f.Append(btempString + Bline + "\n").ToString());
            }
        }
        output.Close();
       // Console.ReadLine();
    }
}

我现在陷入困境,我不知道如何浏览每个词典并比较键,然后仅联接(插入?)具有匹配键的行。

首先,我认为您应该使用该类。 我为这个问题制作的课程非常简单:

class WbsElement
{
    public string PurchasingDocument;
    public string PurchaseOrderText;
    public string ValCoAreaCrcyA;
    public string ValCoAreaCrcyB;
    public string RefDocumentNumber;
    public string Name;
}

它具有一些可用于存储数据的属性。 然后,我将您的代码更改为以下代码:

private static void Main(string[] args)
    {
        StreamReader a = new StreamReader(@"A.CSV");
        StreamReader b = new StreamReader(@"B.CSV");
        StreamWriter output = new StreamWriter(@"output.csv");
        Dictionary<string, WbsElement> newDict = new Dictionary<string, WbsElement>();


        output.WriteLine(a.ReadLine() + "," + b.ReadLine());

        while (!a.EndOfStream && !b.EndOfStream)
        {
            //section for A
            string Aline = a.ReadLine();
            string[] Atokens = Aline.Split(','); //split the line into array
            if (newDict.ContainsKey(Atokens[0]))
            {
                newDict[Atokens[0]].PurchasingDocument = Atokens[1];
                newDict[Atokens[0]].PurchaseOrderText = Atokens[2];
                newDict[Atokens[0]].ValCoAreaCrcyA = Atokens[3];
            }
            else
            {
                WbsElement elementToAdd = new WbsElement();
                elementToAdd.PurchasingDocument = Atokens[1];
                elementToAdd.PurchaseOrderText = Atokens[2];
                elementToAdd.ValCoAreaCrcyA = Atokens[3];
                newDict.Add(Atokens[0], elementToAdd);
            }
        }
        while (!b.EndOfStream)
        {
            //section for B
            string Bline = b.ReadLine();
            string[] Btokens = Bline.Split(',');
            if (newDict.ContainsKey(Btokens[0]))
            {
                newDict[Btokens[0]].RefDocumentNumber = Btokens[1];
                newDict[Btokens[0]].ValCoAreaCrcyB = Btokens[2];
                newDict[Btokens[0]].Name = Btokens[3];
            }
            else
            {
                WbsElement elementToAdd = new WbsElement();
                elementToAdd.RefDocumentNumber = Btokens[1];
                elementToAdd.ValCoAreaCrcyB = Btokens[2];
                elementToAdd.Name = Btokens[3];
                newDict.Add(Btokens[0], elementToAdd);
            }
        }

        foreach (KeyValuePair<string, WbsElement> keyValuePair in newDict)
        {
            output.WriteLine(string.Format("{0},{1},{2},{3},{4},{5},{6},{7}", keyValuePair.Key, keyValuePair.Value.PurchasingDocument,
                             keyValuePair.Value.PurchaseOrderText, keyValuePair.Value.ValCoAreaCrcyA,
                             keyValuePair.Key,
                             keyValuePair.Value.RefDocumentNumber, keyValuePair.Value.ValCoAreaCrcyB,
                             keyValuePair.Value.Name));
        }

        output.Close();
        // Console.ReadLine();
    }

我制作了一个新字典,用于存储键和我所创建类的一个实例。 当我再次找到相同的键时,只需将信息添加到类中。 在应用程序的最后,我只是将所有正确的数据刷新到输出流。 该类是使此操作变得简单的关键。

如果您希望它适用于不同长度的数据输入,则可以使用以下命令:

private static void Main(string[] args)
    {
        StreamReader a = new StreamReader(@"A.CSV");
        StreamReader b = new StreamReader(@"B.CSV");
        StreamWriter output = new StreamWriter(@"output.csv");
        Dictionary<string, List<string>> newDict = new Dictionary<string, List<string>>();
        string aLine = a.ReadLine();
        int aLength = aLine.Split(',').Count();

        output.WriteLine(aLine + "," + b.ReadLine());

        while (!a.EndOfStream && !b.EndOfStream)
        {
            //section for A
            string Aline = a.ReadLine();
            string[] Atokens = Aline.Split(','); //split the line into array
            if (newDict.ContainsKey(Atokens[0]))
            {
                for (int i = 0; i < Atokens.Length; i++)
                {
                    newDict[Atokens[0]][i] = Atokens[i];
                }
            }
            else
            {
                List<string> listToAdd = new List<string>();
                for (int i = 0; i < Atokens.Length; i++)
                {
                    listToAdd.Add(Atokens[i]);
                }
                newDict.Add(Atokens[0], listToAdd);
            }
        }
        while (!b.EndOfStream)
        {
            //section for B
            string Bline = b.ReadLine();
            string[] Btokens = Bline.Split(',');
            if (newDict.ContainsKey(Btokens[0]))
            {


                if (newDict[Btokens[0]].Count > aLength)
                {
                    for (int i = 0; i < Btokens.Length; i++)
                    {
                        newDict[Btokens[0]][i + aLength] = Btokens[i];
                    }
                }
                else
                {
                    for (int i = 0; i < Btokens.Length; i++)
                    {
                        newDict[Btokens[0]].Add(Btokens[i]);
                    }
                }
            }
            else
            {
                List<string> listToAdd = new List<string>(aLength);
                listToAdd.AddRange(Btokens);
                newDict.Add(Btokens[0], listToAdd);
            }
        }

        foreach (KeyValuePair<string, List<string>> keyValuePair in newDict)
        {
            string outputLine = string.Empty;
            foreach (string s in keyValuePair.Value)
            {
                if (outputLine != string.Empty)
                {
                    outputLine += ",";
                }
                outputLine += s;
            }
            output.WriteLine(outputLine);
        }

        output.Close();
        // Console.ReadLine();
    }

它使用列表来跟踪输入数据。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM