C# - 重复更改

时间:2011-07-19 17:24:25

标签: c# string split duplicates

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

R.D.    P.N.      X       Y        Rot  Pkg
L5      120910    64.770  98.425   180  SOP8                    
P4      120911   -69.850  98.425   180  SOIC12                    
L10     120911   -19.685  83.820   180  SOIC10                    
P4      120911    25.400  83.820   180  0603                    
L5      120910    62.484  98.425   180  SOP8
L5      120910    99.100  150.105  180  SOP8
..      ......    ......  ......   ..   .......

我想使用string.Split()拆分每个字符串,然后检查每一行上“string [0]”的第一个值。如果有相同字符串[0]的重复项,我想在字符串[0]的末尾添加一个递增的“ - #”。所以它会像string[0] + "-i" .....

我的意思是,对于上面的.txt中的L5,它们会更改为L5-1L5-2L5-3。同样适用于P4(即P4-1P4-2)....


所以新的.txt看起来像这样:

R.D.      P.N.      X       Y        Rot  Pkg
L5-1      120910    64.770  98.425   180  SOP8                    
P4-1      120911   -69.850  98.425   180  SOIC12                    
L10       120911   -19.685  83.820   180  SOIC10                    
P4-2      120911    25.400  83.820   180  0603                    
L5-2      120910    62.484  98.425   180  SOP8
L5-3      120910    99.100  150.105  180  SOP8
..      ......    ......  ......   ..   .......

问题:

  • 我该怎么做呢?
  • 了解如何操作的任何帮助?

4 个答案:

答案 0 :(得分:5)

如果对于仅包含一个匹配项的所有值都为-1,那么这是一个示例程序。您必须在最后复制,因为在编写新文件时无法删除原始文件。

// Replace c:\temp\temp.txt with you original file.
// Replace c:\temp\temp2.txt with your temporary new file.

using (var r = new StreamReader(@"c:\temp\temp.txt"))
{
    using (var w = new StreamWriter(@"c:\temp\temp2.txt"))
    {
        string line;
        var counter = new Dictionary<string, int>();

        // write header first, no changes necessary
        if ((line = r.ReadLine()) != null)
        {
            w.WriteLine(line);
        }

        while ((line = r.ReadLine()) != null)
        {

            // assuming it is safe to split on a space
            var values = line.Split(' ');

            // if the value hasn't been encountered before, add it
            if (!counter.ContainsKey(values[0]))
            {
                // start counter at 0
                counter.Add(values[0], 0);
            }

            // increment the count as we hit each occurrence of the
            // given key
            counter[values[0]] = counter[values[0]] + 1;

            // write out the original line, replacing the key with the
            // format key-#
            w.WriteLine(line.Replace(values[0], 
                                     string.Format("{0}-{1}", 
                                                   values[0], 
                                                   counter[values[0]])));
        }
    }
}

示例输入:

R.D.    P.N.      X       Y        Rot  Pkg
L5      120910    64.770  98.425   180  SOP8                    
P4      120911   -69.850  98.425   180  SOIC12                    
L10     120911   -19.685  83.820   180  SOIC10                    
P4      120911    25.400  83.820   180  0603                    
L5      120910    62.484  98.425   180  SOP8
L5      120910    99.100  150.105  180  SOP8

样本输出(已测试):

R.D.    P.N.      X       Y        Rot  Pkg
L5-1    120910    64.770  98.425   180  SOP8                    
P4-1    120911   -69.850  98.425   180  SOIC12                    
L10-1   120911   -19.685  83.820   180  SOIC10                    
P4-2    120911    25.400  83.820   180  0603                    
L5-2    120910    62.484  98.425   180  SOP8
L5-3    120910    99.100  150.105  180  SOP8

如果您不想要-1,则可以在写入之前始终进行检查,以确保计数为&gt; 1。

答案 1 :(得分:2)

我该怎么做:

  1. 打开要读取的文件,打开另一个要写入的文件。
  2. 从原始文件中读取标题,写入新文件。
  3. 将空字符串创建为int字典。
  4. 开始循环:
  5. 读取行,拆分名称。
  6. 如果字典中不存在该名称,请将其作为整数值为1的键添加到字典中。
  7. 为给定名称附加名称+字典值(例如,名称为“L5”,整数为3,因此附加“L5-3”)以及该行的其余内容(从步骤5保存)到新文件。
  8. 增加给定名称的字典值。
  9. 从第4步开始重复。
  10. 删除旧文件,更改新文件名以匹配上一个文件。
  11. 编辑字典示例:

    //Create an empty dictionary
    Dictionary<string, int> dictionary = new Dictionary<string, int>();
    
    //Add a key/value pair
    dictionary.Add("L5", 1);
    
    //Check if the value exists, if not then add it
    if( !dictionary.ContainsKey("L9") )
        dictionary.Add("L9", 1);
    
    //Get the value (after making sure the value exists)
    int value = dictionary["L5"];
    
    //Increment the value
    dictionary["L5"] = value + 1;
    

    如果您知道字典已包含该密钥,则应该只使用dictionary[string]语法,否则可能会出错。另一种方法是使用TryGetValue方法:

    int value;
    if( dictionary.TryGetValue("L5", out value) )
    {
        //Key exists already
        Console.WriteLine("L5 has a value of {0}", value);
    }
    else
    {
        //Key does not exist
        dictionary.Add("L5", 1);
    }
    

答案 2 :(得分:1)

这个怎么样:

 string[] input = {"R.D.    P.N.      X       Y        Rot  Pkg",
"L5 120910    64.770  98.425   180  SOP8",
"P4      120911   -69.850  98.425   180  SOIC12",
"L10     120911   -19.685  83.820   180  SOIC10",
"P4      120911    25.400  83.820   180  0603",
"L5      120910    62.484  98.425   180  SOP8",
"L5      120910    99.100  150.105  180  SOP8"};

    var control = new Dictionary<string, int>();
    var result = new List<string[]>();

    foreach (var line in input)
    {
       var array = line.Split(' ');
       result.Add(array);
       int occurencies = 0;
       ;
       control[array[0]] = control.TryGetValue(array[0], out occurencies) 
                           ? occurencies == 1 ? -2 : occurencies - 1
                           : 1;
    }

    foreach (var item in result.AsEnumerable().Reverse())
    {
       int value = control[item[0]];
       if (value < 0)
       {
          control[item[0]] = value + 1;
          item[0] = item[0] + value;     
       }
    }

这将为您提供您所追求的结果。可能有更有效的方法,但是,对于800行,这应该足够好了。

答案 3 :(得分:0)

800行非常小。

  1. 浏览数组,并将第一列添加到字典中。在添加到字典测试之前,查看该值是否出现在其中。如果是,只需递增计数器。

  2. 浏览你的字典。对于值大于1的每个键,循环数组并将“-1”,“ - 2”等附加到键的所有出现位置。 ..

  3. 效率不高,但很容易实现