Есть ли приятный, эффективный способ вызова одного и того же метода дважды с двумя разными аргументами? - PullRequest
1 голос
/ 28 ноября 2008

Скажем, например, у меня есть следующая строка:

var testString = "Привет, мир";

И я хочу вызвать следующие методы:

var newString = testString.Replace ("Hello", "") .Replace ("world", "");

Есть ли какая-то конструкция кода, которая упрощает это, так что мне нужно указать метод Replace только один раз и указать несколько параметров, передаваемых ему за один раз?

Ответы [ 10 ]

5 голосов
/ 28 ноября 2008

Еще один вариант сделать это более читабельным - добавить новые строки и правильные отступы (что было бы для меня лучшим вариантом):

var newString = testString.Replace("Hello", "")
                          .Replace("world", "")
                          .Replace("and", "")
                          .Replace("something", "")
                          .Replace("else","");
3 голосов
/ 28 ноября 2008

В некоторых языках (например, python) существует концепция функции уменьшения или сгиба, которая представляет собой функциональный способ представления циклов по всем элементам списка.

С помощью Reduce вы можете написать что-то вроде этого

return reduce(lambda a, x: a.Replace(x, ''), ['hello', 'world'], initial)

, что совпадает с

a = initial
for x in ['hello', 'world']:
    a = a.Replace(x, '')
return a

В python вы также можете произнести это как

reduce(str.replace, ['hello', 'world'], initial).

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

3 голосов
/ 28 ноября 2008

Создайте функцию, в которую вы передаете String и Dictionary(String, String). Итерируйте по каждому элементу в Словаре и InputString.Replace(DictionaryEntry.Key, DictionaryEntry.Value). Вернуть строку с замененными значениями.

Но я бы просто сделал .Replace.Replace, если бы это только 2 раза ...

2 голосов
/ 28 ноября 2008

Как отмечалось в других постах, есть много способов.

Но в целом сладкий = эффективный (= обслуживаемый) = простой. Вероятно, лучше не пытаться, если только по какой-то причине вы не описываете контекст вопроса.

1 голос
/ 28 ноября 2008

Вы можете сделать это с помощью регулярного выражения, например:

var newString = Regex.Replace(testString, "Hello|world", "");

Если вы хотите построить регулярное выражение из последовательности, это будет примерно так:

var stringsToReplace = new[] { "Hello", "world" };
var regexParts = stringsToReplace.Select(Regex.Escape);
var regexText = string.Join("|", regexParts.ToArray());
1 голос
/ 28 ноября 2008

Вы можете создать свой собственный метод расширения Replace, который принимает параметр IEnumberable. Затем переберите итератор и используйте метод replace.

Тогда вы можете назвать это так .Replace (новая строка [] {"Matt", "Joanne", "Robert"}, "")

Я думаю, что это должно сделать

public static string Replace(this string s, IEnumerable<string> strings, string replacementstring)
{
    foreach (var s1 in strings)
    {
        s = s.Replace(s1, replacementstring);
    }

    return s;
}
1 голос
/ 28 ноября 2008

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

0 голосов
/ 28 ноября 2008

Я наблюдаю несколько ловушек в этих шаблонах - во-первых, строки с неизменяемыми вызовами заменяют несколько раз или в цикле, что может быть плохо, особенно если ваша входная строка велика. Если вы одержимы вызовом replace, то хотя бы используйте метод Replace в классе StringBuilder.

0 голосов
/ 28 ноября 2008

Многие люди говорят, что вы должны использовать IEnumerable, List и Arrays и тому подобное, и хотя это совершенно нормально, я бы предпочел использовать ключевое слово params в C # на вашем месте. ЕСЛИ я должен был реализовать что-то вроде этого - что я, вероятно, не хотел бы делать для чего-то такого простого, как ваши двойные вызовы метода Replace ...

0 голосов
/ 28 ноября 2008

Не знаю, слаще ли это, но вы можете сделать:

string inputString = "Hello, world";
string newString = new[] { "Hello", "world" }.Aggregate(inputString, (result, replace) => result.Replace(replace, ""));

Это начнется с входной строки в качестве начального числа и запустит функцию с каждой из строк замены.

Лучшим примером для понимания функции Aggregate может быть:

List<Payment> payments = ...;
double newDebt = payments.Aggregate(oldDebt, (debt, payment) => debt - payment.Amount);
...