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

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

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

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

var newString = testString.Replace("Привет", "").Replace("мир", "");

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


person Jonathan    schedule 27.11.2008    source источник


Ответы (10)


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

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

person Vincent Van Den Berghe    schedule 27.11.2008

Другой вариант сделать это более читабельным — добавить новые строки и правильный отступ (что было бы для меня лучшим вариантом):

var newString = testString.Replace("Hello", "")
                          .Replace("world", "")
                          .Replace("and", "")
                          .Replace("something", "")
                          .Replace("else","");
person Erik van Brakel    schedule 27.11.2008

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

Используя сокращение, вы можете написать что-то вроде этого

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

что то же самое, что

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

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

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

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

person tatwright    schedule 28.11.2008

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

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

person dkretz    schedule 27.11.2008

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

person David Rodríguez - dribeas    schedule 27.11.2008

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

Тогда вы могли бы назвать это так .Replace(new string[] {"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;
}
person terjetyl    schedule 27.11.2008
comment
зачем возиться с IEnumberable? а не просто использовать ключевое слово params? - person Ray; 28.11.2008
comment
Это работает, но мне кажется немного сомнительным. Я бы использовал это, только если бы мне пришлось заменить много значений за один раз во многих местах. Я не могу придумать правильный пример, где это было бы применимо. - person Erik van Brakel; 28.11.2008
comment
@Ray: видя, что все остальные параметры этого метода являются строками, это может сбивать с толку, когда вы используете params string[] strings. - person Erik van Brakel; 28.11.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());
person Greg Beech    schedule 28.11.2008

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

person Thomas Hansen    schedule 28.11.2008

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

person keithwarren7    schedule 28.11.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);
person Hallgrim    schedule 27.11.2008