2015-04-15 5 views
4

Попытка для обертки каждой строки в массиве, но он не работает, значит Еогеасп цикл, объясните, пожалуйста, почемуLinq лямбда Еогеасп

string s = "keepsakes,table runners,outdoor accessories"; 
List<string> keys = s.Split(',').ToList(); 
keys.ForEach(x => x = String.Concat("%", x, "%")); 
s = String.Join(",", keys); 
Console.WriteLine(s); 

нужно получить "%keepsakes%,%table runners%,%outdoor accessories%"

UPD: Спасибо большого для предложений (это точно так же)

но кто-то может ответить, почему это работает, а не работает:

объекта

public class MyItems 
    { 
     public string Item { get; set; } 
    } 

и функ

 string s = "keepsakes,table runners,outdoor accessories"; 
     List<MyItems> keys = s.Split(',').ToList().Select(x => new MyItems(){ Item = x }).ToList(); 
     keys.ForEach(x => x.Item = String.Concat("%", x.Item, "%")); 
     s = String.Join(",", keys.Select(x => x.Item).ToList()); 
     Console.WriteLine(s); 
+1

«это не работает» - что происходит точно? Каков фактический результат? Кроме того, что вы подразумеваете под «массивом»? –

+0

Я обновил свой ответ, пожалуйста, проверьте его – codingadventures

ответ

2

Другой подход может быть с помощью Regex вместо LINQ:

string s = "keepsakes,table runners,outdoor accessories"; 
string pattern = "\\,+"; 
string replacement = "%,"; 

Regex rgx = new Regex(pattern); 
string result = string.Format("%{0}%", rgx.Replace(s, replacement)); 

Edit:

Причина, по которой он работает, используя класс для назначения строки, потому что, когда y НУ использовать Еогеасп в первом случае:

keys.ForEach(x => x = String.Concat("%", x, "%")); 

х, элементы ключей, которые являются строкой, является ссылка передается по значению к функции ForEach. Возьмите это в качестве примера:

var myString = "I'm a string"; 

Console.WriteLine(myString); 

ChangeValue(myString); 

Console.WriteLine(myString); 

void ChangeValue(string s) 
{ 
    s = "something else"; 
} 

Если вы бежите, что фрагмент кода вы увидите, что myString не будет изменено внутри метода ChangeValue, потому что мы пытаемся заменить ссылку. То же самое происходит и для метода ForEach, это основная причина, по которой вы не можете изменить значение своего списка в пределах ForEach.

Вместо если вы:

class MyClass{ 
    public string aString; 
} 

void ChangeValue(MyClass s) 
{ 
    s.aString = "something else"; 
} 

var myClass = new MyClass(); 
myClass.aString = "I'm a string"; 

Console.WriteLine(myClass.aString); 

ChangeValue(myClass); 

Console.WriteLine(myClass.aString); 

Вы признаете, что во втором Console.WriteLine значение поля aString будет изменено на «что-то другое». Here - хорошее объяснение того, как ссылочные типы передаются по значению

+0

Пожалуйста, если вы можете - смотреть на ОБНОВЛЕНО ответ – AleksP

+0

@AleksP Я отредактировал свой ответ – codingadventures

10

Вы не изменяете список в ForEach, вы просто создать строки, которые назначены к локальным переменным x, но затем выброшены. Вы можете использовать for -loop:

for(int i = 0; i < keys.Count; i++) 
{ 
    keys[i] = String.Concat("%", keys[i], "%"); 
} 

Для чего это стоит, вот короче LINQ версия, которая также обходит основной вопрос:

s = string.Join(",", s.Split(',').Select(str => "%" + str + "%")); 
+1

единственный ответ с объяснением! – wudzik

+0

Пожалуйста, если вы можете - посмотрите UPDated ответ – AleksP

+0

Кроме того, второй фрагмент кода работает, поэтому я не понимаю, «может кто-нибудь ответить, почему это работает, и ** не работает ** под ...» _ –

1

List<>.ForEach не может быть использован для изменения содержимого списка , Вы можете создать новый список или использовать цикл for.

keys = keys.Select(x => "%" + x + "%").ToList(); 

или

for(int i = 0; i < keys.Count; i++) 
{ 
    keys[i] = "%" + keys[i] + "%"; 
} 
4

Вы можете использовать Join и Select и Format

string s = "keepsakes,table runners,outdoor accessories"; 

var output = string.Join(",", s.Split(',').Select(x => string.Format("%{0}%", x))); 
+0

Пожалуйста, если хотите - посмотрите UPDated ответ – AleksP

+0

Добавлено обновление для вас –

+1

@DaveBish: ваше обновление неверно. Второй фрагмент работает в отличие от первого, и я думаю, что ОП задается вопросом, почему. Причина не связана с неизменностью строк, но он изменяет свойство ссылочного типа вместо того, чтобы пытаться заменить всю ссылку в «List.ForEach». –

3

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

string s = "keepsakes,table runners,outdoor accessories"; 
string s2 = "%" + s.Replace("," , "%,%") + "%"; 
+0

Пожалуйста, если вы можете - посмотреть на ОБНОВЛЕНО ответ – AleksP

1

Как отмечали другие, лямбда, прошедшая до List.ForEach, не возвращает значение.

LINQ ленив, но String.Join заставит перечисление:

var res = String.Join(",", input.Split(',').Select(s => "%" + s + "%")); 
1

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

string s = "keepsakes,table runners,outdoor accessories"; 
List<string> keys = s.Split(',').Select(x => String.Concat("%", x, "%")).ToList(); 
s = String.Join(",", keys); 
Console.WriteLine(s); 
+0

Пожалуйста, если вы можете - посмотреть на ОБНОВЛЕНО ответ – AleksP

2

Просто другой подход (без лямбды):

string result = string.Concat("%", s, "%").Replace(",", "%,%"); 
+0

Пожалуйста, если вы можете - посмотреть на ОБНОВЛЕНО ответ – AleksP

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