2010-09-14 2 views
3

Можно ли написать лямбда-выражение, которое будет проходить через массив объектов и заменить все вхождения «X», «Y», «» и «Z» в одном из свойств?LINQ lambda выражение для замены нескольких символов в строке?

E.g.

return query.Select(x => { x.SomePropertyName= x.SomePropertyName.Trim().Replace(' ', "_"); return x; }).ToList(); 

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

Спасибо

ответ

5

Когда я хочу, чтобы заменить один из нескольких персонажей с одного другим персонажем, я часто использую комбинацию String.split и string.join :

char[] unwanted = new[] {'X', 'Y', 'Z'}; 
query = query.Select(x => 
{ 
    x.SomePropertyName = string.Join("_", x.SomePropertyName.Split(unwanted)); 
    return x; 
}); 

Это заменит любое вхождение 'X', 'Y' или 'Z''_' с. Вы можете комбинировать это с построкой цикла по вашему выбору.

Как обсуждалось в комментариях, использование Select на самом деле не добавляет значения в этом случае. Нормальный foreach цикл будет выполнять работу, и даже производить более компактный код:

char[] unwanted = new[] {'X', 'Y', 'Z'}; 
foreach(var x in query) 
{ 
    x.SomePropertyName = string.Join("_", x.SomePropertyName.Split(unwanted)); 
}; 
+0

Это именно то, что мне нужно. Спасибо – 2010-09-14 14:49:44

+0

Это немного злоупотребляет методом 'Select', хотя! – LukeH

+0

Это работает, если первый или последний символ - «X», «Y» или «Z»? Например. «XBC» возвращает «_BC» и «ABX» возвращает «AB_»? Или «XYZ» возвращает «___»? –

5

Если вы хотите использовать LINQ, вы можете использовать Select, ToArray и String (символ []) конструктор, как это:

var result = query.ToList(); 
foreach (var x in result) 
{ 
    x.SomeProperty = 
     new string(x.SomeProperty 
        .Select(c => (c == 'X' || ... || c == ' ') ? '_' : c) 
        .ToArray()); 
} 

Заметьте, что LINQ не предназначен, чтобы быть используется для создания побочных эффектов, но для создания новых перечислений из существующих счетчиков. Итак, здесь лучше провести цикл foreach.


Но почему бы не просто цепочку Замены?

var result = query.ToList(); 
foreach (var x in result) 
{ 
    x.SomeProperty = x.SomeProperty 
         .Replace('X', '_') 
         .Replace('Y', '_') 
         .Replace('Z', '_') 
         .Replace(' ', '_'); 
} 

Или вы пытаетесь заменить один символ с последовательностью символов? Затем используйте перегрузку string.replace, который принимает две строки:

var result = query.ToList(); 
foreach (var x in result) 
{ 
    x.SomeProperty = x.SomeProperty.Replace(" ", "ABC"); 
} 
+0

Спасибо за это! – 2010-09-14 14:50:08

2

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

query.Select(
    x => { 
     x.SomePropertyName = Regex.Replace(x.SomePropertyName, @"[XYZ\s]", "_"); 
     return x; }) 
0

проведите через каждый символ в строке и при необходимости замените его.

var xyz = new HashSet<char>(new[] { 'X', 'Y', 'Z' }); 
char replacement = '_'; 
var results = query 
    .Select(x => 
    { 
     var value = x.SomePropertyName 
    .Trim() 
    .Select(y => xyz.Contains(y) ? replacement : y) 
    .ToArray(); 
     x.SomePropertyName = new string(value); 
     return x; 
    }) 
    .ToList(); 
1

Хотя вы запросили LINQ, это (ab) использование LINQ полагается на побочные эффекты и загромождает код. Альтернатива для использования с массивом объектов (которые вы заявили это дело в вашем вопросе) будет использовать Array.ForEach method:

// using Fredrik Mörk's approach 
Array.ForEach(query, x => 
    x.SomePropertyName = string.Join("_", x.SomePropertyName.Split(unwanted))); 

// using Regex 
Array.ForEach(query, x => x.SomePropertyName = 
    Regex.Replace(x.SomePropertyName, "[XYZ]", "_", RegexOptions.IgnoreCase)); 

Конечно использование регулярных выражений требует определенных знаний. Помните об использовании метасимволов, которые имеют особое значение в регулярном выражении. Вы можете дезинфицировать своих персонажей, используя Regex.Escape method.

+0

Человек ... это даже менее разборчиво, чем LINQ ... (я имею в виду подход с регулярным выражением) – code4life

Смежные вопросы