C# 林克兰姆达弗雷奇
试图在数组中包装每个字符串,但它不起作用,这意味着foreach循环,请解释原因C# 林克兰姆达弗雷奇,c#,linq,lambda,C#,Linq,Lambda,试图在数组中包装每个字符串,但它不起作用,这意味着foreach循环,请解释原因 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)
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);
和func
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);
string s=“纪念品、桌椅、户外配件”;
列表键=s.Split(',').ToList().Select(x=>newmyitems(){Item=x}).ToList();
keys.ForEach(x=>x.Item=String.Concat(“%”,x.Item,“%”);
s=String.Join(“,”,keys.Select(x=>x.Item.ToList());
控制台。写入线(s);
您不是在ForEach
中修改列表,您只是在创建分配给局部变量x
的字符串,然后将其丢弃。您可以为-循环使用:
for(int i = 0; i < keys.Count; i++)
{
keys[i] = String.Concat("%", keys[i], "%");
}
List.ForEach
不能用于更改列表的内容。您可以创建新列表,也可以使用for
循环
keys = keys.Select(x => "%" + x + "%").ToList();
或
for(int i=0;i
您可以使用Join
和选择
和格式
string s = "keepsakes,table runners,outdoor accessories";
var output = string.Join(",", s.Split(',').Select(x => string.Format("%{0}%", x)));
您可以做得更简单:将每个逗号替换为%,%%
string s = "keepsakes,table runners,outdoor accessories";
string s2 = "%" + s.Replace("," , "%,%") + "%";
正如其他人所指出的,传递给列表的lambda.ForEach
不返回值
LINQ是惰性的,但String.Join
将强制枚举:
var res = String.Join(",", input.Split(',').Select(s => "%" + s + "%"));
ForEach不会更改字符串列表,它只会使用每个字符串执行一个操作。相反,您可以这样做:
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);
string s=“纪念品、桌椅、户外配件”;
列表键=s.Split(',')。选择(x=>String.Concat(“%”,x,“%”)。ToList();
s=String.Join(“,”键);
控制台。写入线(s);
只是另一种方法(没有lambdas):
另一种方法是使用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));
编辑:
它之所以使用类来分配字符串,是因为在第一个实例中使用foreach时:
keys.ForEach(x => x = String.Concat("%", x, "%"));
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);
您确认在第二个控制台.WriteLine
中,字段aString的值将更改为“其他内容”。这是一个很好的解释,说明了引用类型是如何通过值传递的。“它不起作用”-到底发生了什么?实际产量是多少?还有,你所说的“数组”是什么意思?我更新了我的答案,请检查一下,这是唯一一个有解释的答案!请,如果你可以-看看更新的答案除此之外,第二个代码段是有效的,所以如果你不理解为什么它与类的属性一起工作,我不理解“有人能回答为什么这个工作而不是在…”。原因是类MyItems
是引用类型,并且您正在修改List.ForEach
中每个引用的属性。通过这种方式,您可以修改列表中的原始对象,这与您尝试替换引用本身的第一种方法不同answer@DaveBish:您的更新不正确。第二个代码段与第一个代码段相反,我想OP想知道为什么。原因与字符串的不变性无关,而是他更改了引用类型的属性,而不是试图替换列表中的整个引用。ForEach
。请,如果可以-查看更新的应答请,如果可以-查看更新的应答请,如果可以-查看更新的应答请,如果可以,请查看更新的答案
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));
keys.ForEach(x => x = String.Concat("%", x, "%"));
var myString = "I'm a string";
Console.WriteLine(myString);
ChangeValue(myString);
Console.WriteLine(myString);
void ChangeValue(string s)
{
s = "something else";
}
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);