我需要更新IEnumerable列表中的值。
这是一个简短的IEnumerable示例:
IEnumerable<string> allsubdirs = new List<string>() { "a", "b", "c" };
现在,如果我想为每个项目添加时间戳,这不起作用:
allsubdirs.Select(a => a = a + "_" + DateTime.Now.ToString("hhmmss")).ToList();
这两个都没有:
foreach (var item in allsubdirs)
item = item + "_" + DateTime.Now.ToString("hhmmss");
我让它像这样工作:
IEnumerable<string> newallsubdirs = allsubdirs.Select(a => a + "_" + DateTime.Now.ToString("hhmmss")).ToList();
allsubdirs = newallsubdirs;
但这看起来好像在作弊。请问这样做的正确方法是什么?
答案 0 :(得分:21)
Linq用于查询,而非更新。 Linq查询根据投影,过滤器等返回 new 集合。因此,您的选择是:
保存&#34;新&#34;收集回变量(或必要时的新变量):
allsubdirs = allsubdirs.Select(a => a = a + "_" + DateTime.Now.ToString("hhmmss")).ToList();
使用IList<T>
和for
循环等可写界面:
IList<string> allsubdirs = new List<string>() { "a", "b", "c" };
for(int i=0; i<allsubdirs.Count(); i++)
allsubdirs[i] = allsubdirs[i] + "_" + DateTime.Now.ToString("hhmmss");
主要区别在于Select
不修改原始集合,而for
循环则不会。
我的观点是,Select
更清洁,而不是作弊&#34; - 您只是在原始集合的顶部添加投影。
答案 1 :(得分:2)
你的第一次尝试
allsubdirs.Select(a => a = a + "_" + DateTime.Now.ToString("hhmmss")).ToList();
返回新的IEnumerable
,但不会更改旧的allsubdirs = allsubdirs.Select(a => a + "_" + DateTime.Now.ToString("hhmmss")).ToList();
。为此用途
{{1}}
答案 2 :(得分:0)
试试这个: -
var result= allsubdirs.Select(x => String.Format("{0}_{1}", x,
DateTime.Now.ToString("hhmmss")));
如果您不想将其存储在另一个变量中,请考虑使用ToList()
。
答案 3 :(得分:0)
如现有答案中所述,尝试为其中一个元素分配新值时,无法修改IEnumerable
集合。
但是,如果集合中包含的元素是可变类型,则可以修改它们。但是对于你的例子来说这是不可能的,因为string
是不可变的。
因此,如果要修改IEnumerable
中的现有元素,则元素本身应该是支持修改操作的类型,如下例所示。
public class MyItem
{
private string _value;
public MyItem(string content)
{
_value = content;
}
public void Append(string other)
{
_value += other;
}
public void ReplaceWith(Func<string, string> replacer)
{
_value = replacer(_value);
}
}
然后你可以像这样使用它:
IEnumerable<MyItem> allsubdirs = new List<MyItem>() { new MyItem("a"), new MyItem("b"), new MyItem("c") };
foreach (var item in allsubdirs)
item.Append("_" + DateTime.Now.ToString("hhmmss"));
答案 4 :(得分:0)