【问题标题】:Create a larger string from an array of strings从字符串数组创建一个更大的字符串
【发布时间】:2019-02-16 18:12:21
【问题描述】:

我有一个字符串数组,看起来像这样

var input = new [] { "AB-PQ", "PQ-EF", "EF=CD", "CD-IJ", "IJ=XY", "XY-JK" };

我想要一个字符串输出,应该是这样的

var output = "AB-PQ-EF=CD-IJ=XY-JK"

我想知道是否有更好的方法来做到这一点,而不是使用蛮力 for 循环,然后使用字符串生成器进行拆分和组合。

我的业务用例: 我的业务用例是,给定的字符串表示包含多个城市的路线中两个城市之间的链接序列。 “-”表示公路连接,“=”表示铁路连接。城市代码可以是任意长度。

【问题讨论】:

  • 这里的主要问题是您已经描述了最终结果,这意味着您将获得专注于获得特定最终结果的答案,而不是如何到达那里。
  • new[] { "AB-BC", "CD-DE", "BC-CD" } 怎么样? (注意顺序)
  • 您需要描述从第一个到第二个所遵循的规则,否则每次您想出更多信息时,每个答案都会是“是的,但是......”在这里,那只会浪费大家的时间。
  • 我认为是否有任何答案实际上比您的“蛮力循环”更好是值得怀疑的。 Linq 仍在遍历数组中的每一项,但循环中的逻辑会更加清晰。把它简化为一行代码很好,但是当它需要 6 或 7 个步骤时,它的可读性不是很好。
  • @Enigmativity 对此我感到抱歉。我会更新我的问题。感谢您指导初学者:)

标签: c# arrays .net string split


【解决方案1】:

这行得通:

var input = new [] { "AB-PQ", "PQ-EF", "EF=CD", "CD-IJ", "IJ=XY", "XY-JK" };

var output = String.Join("",
    input.Take(1).Concat(new [] { String.Join("", input.Skip(1).Select(x => x.Substring(2))) }));

我不喜欢它,但它有效。它产生"AB-PQ-EF=CD-IJ=XY-JK"


试试这个作为更强大的替代方案:

void Main()
{
    var input = new[] { "AB-PQ", "PQ-XYZ", "XYZ=CD", "CD-A", "A=XY", "XY-JK" };

    var output =
        input
            .Select(i => new Segment(i))
            .Aggregate(
                "",
                (a, x) => a + x.ToString().Substring(a == "" ? 0 : x.Origin.Length));
}

public enum Mode
{
    Road, Rail
}

public sealed class Segment : IEquatable<Segment>
{
    private readonly string _origin;
    private readonly Mode _mode;
    private readonly string _destination;

    public string Origin { get { return _origin; } }
    public Mode Mode { get { return _mode; } }
    public string Destination { get { return _destination; } }

    public Segment(string descriptor)
    {
        var parts = descriptor.Split('-', '=');
        if (parts.Length != 2)
        {
            throw new System.ArgumentException("Segment descriptor must contain '=' or '-'.");
        }
        _origin = parts[0];
        _mode = descriptor.Contains("=") ? Mode.Rail : Mode.Road;
        _destination = parts[1];
    }

    public Segment(string origin, Mode mode, string destination)
    {
        _origin = origin;
        _mode = mode;
        _destination = destination;
    }

    public override bool Equals(object obj)
    {
        if (obj is Segment)
            return Equals((Segment)obj);
        return false;
    }

    public bool Equals(Segment obj)
    {
        if (obj == null) return false;
        if (!EqualityComparer<string>.Default.Equals(_origin, obj._origin)) return false;
        if (!EqualityComparer<Mode>.Default.Equals(_mode, obj._mode)) return false;
        if (!EqualityComparer<string>.Default.Equals(_destination, obj._destination)) return false;
        return true;
    }

    public override int GetHashCode()
    {
        int hash = 0;
        hash ^= EqualityComparer<string>.Default.GetHashCode(_origin);
        hash ^= EqualityComparer<Mode>.Default.GetHashCode(_mode);
        hash ^= EqualityComparer<string>.Default.GetHashCode(_destination);
        return hash;
    }

    public override string ToString()
    {
        return $"{_origin}{(_mode == Mode.Rail ? "=" : "-")}{_destination}";
    }

    public static bool operator ==(Segment left, Segment right)
    {
        if (object.ReferenceEquals(left, null))
        {
            return object.ReferenceEquals(right, null);
        }

        return left.Equals(right);
    }

    public static bool operator !=(Segment left, Segment right)
    {
        return !(left == right);
    }
}

【讨论】:

  • 这里写的不一定是 2 个字母的东西。它可以是任何长度。例如AB、XYZ、A、123等
  • @pango89 - 那应该是你的问题。请更新它。还请提供真实数据。
【解决方案2】:

另一个版本:

var input = new [] {"AB-PQ", "PQ-EF", "EF=CD", "CD-IJ", "IJ=XY", "XY-JK"};
var output = string.Join("=", string.Join("-", input).Split('=').Select(x => string.Join("-", x.Split('-').Distinct())))

【讨论】:

    【解决方案3】:
    var input = new [] { "AB-PQ", "PQ-EF", "EF=CD", "CD-IJ", "IJ=XY", "XY-JK" };
    
    var r = input.Aggregate((total, current) => 
                total + current.Substring(OverlappingCharCount(total, current))
            );
    

    您可以将OverlappingCharCount 方法定义为始终返回 2(如在您的示例中,字符串始终正好重叠 2 个字符),或者使用一些更智能的逻辑来处理更通用的情况。

    【讨论】:

      【解决方案4】:

      使用正则表达式实现同样的效果:

      string str = string.Join("-", input);
      Regex oRegex = new Regex(@"\b(?<Captured>\w+)-\1\b",RegexOptions.IgnoreCase);
      oRegex.Matches(str).Cast<Match>().ToList().ForEach(items=>str = str.Replace(items.ToString(), items.Groups["Captured"].ToString()));
      Console.WriteLine(str);
      

      【讨论】:

        【解决方案5】:

        这是完整的答案

        using System;
        using System.Linq;
        
        namespace ConsoleApp1
        {
            class Program
            {
                static void Main(string[] args)
                {
                    var input = new string[] { "AB-PQ", "PQ-EF", "EF=CD", "CD-IJ", "IJ=XY", "XY-JK" };
                    var output = input[0] + string.Join("", input.Skip(1).Select(c => string.Join("", c.Skip(2))));
                    Console.WriteLine(output);
                    Console.ReadLine();
                }
            }
        }
        

        【讨论】:

          【解决方案6】:

          您可以像这样使用LINQstring.Join

          var input = new[]{"AB-PQ", "PQ-EF", "EF=CD", "CD-IJ", "IJ=XY", "XY-JK"};
          var result = input[0] + string.Join("", input.Skip(1)
                                    .Select(c => string.Join("", c.Skip(2))));
          

          别忘了先将它添加到您的 using 指令中:

          using System.Linq;
          

          【讨论】:

            【解决方案7】:

            这是我正在使用的,它似乎正在工作。这很容易理解。

            public static string Get(string[] array)
            {
                var sb = new StringBuilder();
                for (var i = 0; i < array.Length - 1; i++)
                {
                    var link = array[i];
                    var words = link.Split('-', '=');
                    sb.Append(words.First());
            
                    // Link will contain either of the separators
                    if (link.Contains('-'))
                    {
                        sb.Append('-');
                    }
            
                    if (link.Contains('='))
                    {
                        sb.Append('=');
                    }
                }
            
                sb.Append(array.Last());
                return sb.ToString();
            }
            

            【讨论】:

              猜你喜欢
              • 2013-08-11
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多