Linq lambda foreach
Linq lambda foreach
尝试将每个字符串包装在数组中但它不起作用,意味着 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);
需要"%keepsakes%,%table runners%,%outdoor accessories%"
更新:
非常感谢您的建议(都是一样的)
但是有人可以回答为什么这是有效的而不是在以下情况下有效:
对象
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);
您没有修改 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 + "%"));
List<>.ForEach
不能用来改变列表的内容。您可以创建一个新列表或使用 for
循环。
keys = keys.Select(x => "%" + x + "%").ToList();
或
for(int i = 0; i < keys.Count; i++)
{
keys[i] = "%" + keys[i] + "%";
}
您可以使用 Join
和 Select
以及 Format
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("," , "%,%") + "%";
正如其他人所指出的,传递给 List.ForEach
的 lambda 没有 return 值。
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);
另一种方法(没有 lambda):
string result = string.Concat("%", s, "%").Replace(",", "%,%");
另一种方法可以使用 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));
编辑:
它使用 class 分配字符串的原因是,当您在第一个实例中使用 foreach 时:
keys.ForEach(x => x = String.Concat("%", x, "%"));
x,keys的元素,是一个字符串,是一个按值传递给函数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 的值将更改为 "something else"。 Here 很好地解释了引用类型是如何按值传递的
尝试将每个字符串包装在数组中但它不起作用,意味着 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);
需要"%keepsakes%,%table runners%,%outdoor accessories%"
更新: 非常感谢您的建议(都是一样的)
但是有人可以回答为什么这是有效的而不是在以下情况下有效:
对象
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);
您没有修改 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 + "%"));
List<>.ForEach
不能用来改变列表的内容。您可以创建一个新列表或使用 for
循环。
keys = keys.Select(x => "%" + x + "%").ToList();
或
for(int i = 0; i < keys.Count; i++)
{
keys[i] = "%" + keys[i] + "%";
}
您可以使用 Join
和 Select
以及 Format
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("," , "%,%") + "%";
正如其他人所指出的,传递给 List.ForEach
的 lambda 没有 return 值。
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);
另一种方法(没有 lambda):
string result = string.Concat("%", s, "%").Replace(",", "%,%");
另一种方法可以使用 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));
编辑:
它使用 class 分配字符串的原因是,当您在第一个实例中使用 foreach 时:
keys.ForEach(x => x = String.Concat("%", x, "%"));
x,keys的元素,是一个字符串,是一个按值传递给函数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 的值将更改为 "something else"。 Here 很好地解释了引用类型是如何按值传递的