Создать большую строку из массива строк - PullRequest
0 голосов
/ 12 сентября 2018

У меня есть массив строк, который выглядит следующим образом

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

Я хочу получить вывод строки, который должен быть таким:

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

Я хочу знать, есть лилучший способ сделать это вместо использования грубой силы для цикла, а затем расщепления и объединения с помощью построителя строк.

Мой бизнес-пример использования: Мой бизнес-пример таков, что данная строка представляет собой последовательность ссылокмежду двумя городами по маршруту, содержащему несколько городов.«-» означает дорожное сообщение, а «=» означает железнодорожное сообщение.Код города может быть любой длины.

Ответы [ 7 ]

0 голосов
/ 12 сентября 2018

Вот полный ответ

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();
        }
    }
}
0 голосов
/ 13 сентября 2018

Это то, что я использую, и, кажется, работает. Это очень легко понять.

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();
}
0 голосов
/ 12 сентября 2018

Достигните того же, используя Regex:

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);
0 голосов
/ 12 сентября 2018
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 символа), или используйте более разумную логику для обработки более общих случаев.

0 голосов
/ 12 сентября 2018

Другая версия:

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())))
0 голосов
/ 12 сентября 2018

Вы можете использовать LINQ и string.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;
0 голосов
/ 12 сентября 2018

Это работает:

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);
    }
}
...