разбить строку через запятую и добавить кавычки в C# - элегантное решение - PullRequest
2 голосов
/ 09 апреля 2020

У меня string выглядит так:

var v = "10,14,18,21" 

и я хотел бы использовать его как-то так:

'10', '14', '18', '21'

Я написал функцию, которая разбивает значения на запятую и добавляет их обратно в строку. Дополнительно я удаляю последний , из строки результата.

Я поместил все в функцию с именем prep для тестирования.

Функция делает то, что я хочу. Однако мне было интересно, есть ли более элегантный способ добиться того же результата. Вот что я придумал:

public static string prep(string s) {
    string res = "";

    List<string> list = s.Split(',').ToList<string>();

    foreach(var item in list) 
        res += "'" + item + "',";

    res = res.TrimEnd(',');

    return res;
}

Ответы [ 7 ]

6 голосов
/ 09 апреля 2020

Рассматривали ли вы это?

var v = "10,14,18,21";
var r = $"'{v.Replace(",", "', '")}'";

Это дает: '10', '14', '18', '21'

5 голосов
/ 09 апреля 2020

Вы можете попробовать регулярные выражения :

using System.Text.RegularExpressions;

...

string result = Regex.Replace(v, "[^,]+", " '$0'");

, здесь мы заключаем каждый элемент между запятыми в одинарные кавычки.

Редактировать: Как Джухарр указал в комментариях, у нас есть дополнительный пробел в начале строки result. Мы можем либо

удалить это:

result = Regex.Replace(v, "[^,]+", " '$0'").TrimStart();

Или предотвратить это:

string result = Regex
 .Replace(v, "[^,]+", m => $"{(m.Index > 0 ? " ":"")}'{m.Value}'");
4 голосов
/ 09 апреля 2020

Вы можете использовать string.Join() здесь:

var result = string.Join(", ", v.Split(",").Select(x => $"'{x}'"));

Console.WriteLine(result);
// '10', '14', '18', '21'

, который в основном объединяет элементы с помощью ", ", затем проецирует одинарные кавычки вокруг каждой строки с Enumerable.Select() от LINQ.

Вы также можете добавить одинарные кавычки без $ - интерполяция строк :

var result = string.Join(", ", v.Split(",").Select(x => "'" + x + "'"));

Как @ Racil Hilan , на что указывают подсказки в комментариях, здесь LINQ нам не нужен, мы можем просто окружить результат "'" и присоединиться к "', '":

var result = "'" + string.Join("', '", v.Split(",")) + "'";
3 голосов
/ 09 апреля 2020

Одним из способов является использование Select по результату Split, затем string.Join:

public static string prep(string s) {
    var array = s.Split(',');
    // Select takes a lambda that tells it what to do with each item in the array
    var quotesAdded = array.Select(x => $"'{x}'");
    var result = string.Join(", ", quotesAdded);
    return result;
}

Или все в член с выраженным телом :

public static string prep(string s) => string.Join(", ",
    s.Split(',').Select(x => $"'{x}'")
);
2 голосов
/ 09 апреля 2020

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

Примечание: я отказался от строки с 10 000 элементов, разделенных запятыми, потому что метод агрегирования занимал очень много времени.

private static readonly Random Rand = new Random();

private static void Main(string[] args)
{
    for (int size = 10; size <= 1000; size *= 10)
    {
        var input = GenerateInput(size);

        Console.WriteLine($"Size {size}:");
        Console.WriteLine("Average          Total            Method");
        Tester(input, AddSingleQuotesRegExNotCompiled, nameof(AddSingleQuotesRegExNotCompiled));
        Tester(input, AddSingleQuotesRegExCompiled, nameof(AddSingleQuotesRegExCompiled));
        Tester(input, AddSingleQuotesStringReplace, nameof(AddSingleQuotesStringReplace));
        Tester(input, AddSingleQuotesJoinSplitSelectWithInterpolation, nameof(AddSingleQuotesJoinSplitSelectWithInterpolation));
        Tester(input, AddSingleQuotesJoinSplitSelectWithoutInterpolation, nameof(AddSingleQuotesJoinSplitSelectWithoutInterpolation));
        Tester(input, AddSingleQuotesJoinSplit, nameof(AddSingleQuotesJoinSplit));
        Tester(input, AddSingleQuotesSplitSelectAggregate, nameof(AddSingleQuotesSplitSelectAggregate));

        Console.WriteLine();
    }

    Console.ReadLine();
}


public static void Tester(string input, Func<string, string> func, string name)
{
    var sw = Stopwatch.StartNew();
    for (int i = 0; i < 10000; i++)
    {
        func(input);
    }

    sw.Stop();

    Console.Write($"{sw.Elapsed/10000} {sw.Elapsed} {name}");
    Console.WriteLine();
}

public static string GenerateInput(int count)
{
    var builder = new StringBuilder();
    while (count-- > 0)
    {
        builder.Append(Rand.Next(100));
        if (count > 0)
            builder.Append(',');
    }

    return builder.ToString();
}

private static Regex addComma = new Regex("[^,]+", RegexOptions.Compiled);

public static string AddSingleQuotesRegExCompiled(string input) => 
    addComma.Replace(input, "'$0'");
public static string AddSingleQuotesRegExNotCompiled(string input) => 
    Regex.Replace(input, "[^,]+", " '$0'");
public static string AddSingleQuotesStringReplace(string input) => 
    $"'{input.Replace(",", ", ")}'";
public static string AddSingleQuotesJoinSplitSelectWithInterpolation(string input) => 
    string.Join(", ", input.Split(",").Select(x => $"'{x}'"));
public static string AddSingleQuotesJoinSplitSelectWithoutInterpolation(string input) => 
    string.Join(", ", input.Split(",").Select(x => "'" + x + "'"));
public static string AddSingleQuotesJoinSplit(string input) => 
    "'" + string.Join("', '", input.Split(",")) + "'";
public static string AddSingleQuotesSplitSelectAggregate(string input) => 
    input.Split(',')
        .Select(m => "'" + m + "'")
        .Aggregate((tot,next) => tot + "," + next);
}

со следующими результатами

Size 10:
Average          Total            Method
00:00:00.0000053 00:00:00.0526194 AddSingleQuotesRegExNotCompiled
00:00:00.0000031 00:00:00.0309486 AddSingleQuotesRegExCompiled
00:00:00.0000002 00:00:00.0018592 AddSingleQuotesStringReplace
00:00:00.0000017 00:00:00.0169309 AddSingleQuotesJoinSplitSelectWithInterpolation
00:00:00.0000008 00:00:00.0084822 AddSingleQuotesJoinSplitSelectWithoutInterpolation
00:00:00.0000004 00:00:00.0039672 AddSingleQuotesJoinSplit
00:00:00.0000010 00:00:00.0102010 AddSingleQuotesSplitSelectAggregate

Size 100:
Total            Average          Method
00:00:00.0000239 00:00:00.2394021 AddSingleQuotesRegExNotCompiled
00:00:00.0000163 00:00:00.1628607 AddSingleQuotesRegExCompiled
00:00:00.0000015 00:00:00.0149009 AddSingleQuotesStringReplace
00:00:00.0000065 00:00:00.0650797 AddSingleQuotesJoinSplitSelectWithInterpolation
00:00:00.0000069 00:00:00.0693588 AddSingleQuotesJoinSplitSelectWithoutInterpolation
00:00:00.0000034 00:00:00.0338554 AddSingleQuotesJoinSplit
00:00:00.0000129 00:00:00.1287369 AddSingleQuotesSplitSelectAggregate

Size 1000:
Total            Average          Method
00:00:00.0002089 00:00:02.0892826 AddSingleQuotesRegExNotCompiled
00:00:00.0001607 00:00:01.6066026 AddSingleQuotesRegExCompiled
00:00:00.0000144 00:00:00.1444781 AddSingleQuotesStringReplace
00:00:00.0000578 00:00:00.5776627 AddSingleQuotesJoinSplitSelectWithInterpolation
00:00:00.0000580 00:00:00.5801025 AddSingleQuotesJoinSplitSelectWithoutInterpolation
00:00:00.0000296 00:00:00.2957712 AddSingleQuotesJoinSplit
00:00:00.0005631 00:00:05.6307457 AddSingleQuotesSplitSelectAggregate
2 голосов
/ 09 апреля 2020

Еще один подход к решению этой проблемы (без использования LINQ):

public static string prep(string s) =>
    "'" + string.Join("', '", s.Split(",")) + "'";
1 голос
/ 09 апреля 2020

Я предпочитаю использовать агрегат

    string a = "1,2,3,4,5";
    string c = a.Split(',').Select(m => "'" + m + "'").Aggregate((tot,next) => tot + "," + next);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...