C# 将数组的所有值设置为给定值的 Linq 表达式
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1413223/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Linq expression to set all values of an array to a given value
提问by Erik Funkenbusch
I have a bit of code that i'd like to turn into a linq expression (preferably with lambdas) to make it easier to use as a delegate. The code looks like this:
我有一些代码,我想将其转换为 linq 表达式(最好使用 lambdas),以使其更易于用作委托。代码如下所示:
List<DateTime[]> changes = new List<DateTime[]>();
changes = PopulateChanges();
for (int i = 0; i < changes.Count; i++)
{
for(int j = 0; j < changes[i].Length; j++)
{
changes[i][j] = DateTime.MinValue;
}
}
For the life of me, I can't seem to figure this one out. I've tried using ForEach and various forms of select, etc.. nothing seems to work right.
对于我的生活,我似乎无法弄清楚这一点。我试过使用 ForEach 和各种形式的选择等。似乎没有任何效果。
FYI, I know that DateTime defaults to MinValue, in reality this is clearing the arrays to default after they've already been set.
仅供参考,我知道 DateTime 默认为 MinValue,实际上这是在设置数组后将其清除为默认值。
Can anyone help me with a working expression?
谁能帮我一个工作表达?
EDIT:
编辑:
I guess what I'm really saying here is I want a concise way to set all elements of a multi-dimensional array to a given value. Certainly, the nested for loop works, and I can certainly place it in a function (which I have already done). I just want something more concise that can be used more easily in a delegate without creating a multi-line monster.
我想我在这里真正想说的是我想要一种简洁的方法来将多维数组的所有元素设置为给定值。当然,嵌套的 for 循环有效,我当然可以将它放在一个函数中(我已经这样做了)。我只想要更简洁的东西,可以更轻松地在委托中使用,而不会创建多行怪物。
采纳答案by LukeH
This should do the trick.
这应该可以解决问题。
It's not LINQ, and it's not really much different to your nested for
loops, just slightly less verbose.
它不是 LINQ,它与您的嵌套for
循环并没有太大的不同,只是稍微不那么冗长。
changes.ForEach(x => Array.Clear(x, 0, x.Length));
There are certainly ways to (ab)use LINQ to achieve the same results, but I'd consider them to be dirty hacks. Besides, the LINQ equivalent probably wouldn't be any less verbose than my example above.
当然有(ab)使用 LINQ 来实现相同结果的方法,但我认为它们是肮脏的黑客。此外,LINQ 等价物可能不会比我上面的示例更冗长。
回答by dtb
LINQ is not really intended to be used for updating collections. It's about querying, i.e. create enumerables over existing collections. I think your code is perfectly readable and won't improve much if you force it to have lots of lambdas and such.
LINQ 并不真正用于更新集合。它是关于查询的,即在现有集合上创建枚举。我认为你的代码是完全可读的,如果你强迫它有很多 lambdas 等,不会有太大的改进。
If you want to create a new List<DateTime[]>
with each element set to a value, you can do this:
如果要创建一个新List<DateTime[]>
的每个元素设置为一个值,你可以这样做:
var changes = Enumerable.Range(0, width)
.Select(x => Enumerable.Range(0, height)
.Select(y => DateTime.MinValue)
.ToArray())
.ToList();
If you reallywant to do it using ForEach
/LINQ, it's possible to abuse Select
(but I don't recommend it):
如果您真的想使用ForEach
/LINQ来执行此操作,则可能会滥用Select
(但我不建议这样做):
changes.ForEach(array => array.Select((dt, i) => array[i] = DateTime.Now)
.LastOrDefault());
回答by Drew Noakes
An interesting question, but Linq is about queryingand what you're doing here doesn't look much like a query to me. Even if there is a solution out there, I'm not sure I'd use Linq for something like this.
一个有趣的问题,但 Linq 是关于查询的,而你在这里所做的对我来说并不像查询。即使有解决方案,我也不确定我会使用 Linq 来做这样的事情。
回答by feroze
Can you describe some use cases of how you propose to use the said delegate?
您能否描述一些您建议如何使用上述委托的用例?
I mean, if PopulateChanges() is returning you a List<> of DateTime arrays, and you are going through all of them and setting them to DateTime.MinValue, what exactly is the code unit that you want to put in the delegate?
我的意思是,如果 PopulateChanges() 返回一个 DateTime 数组的 List<>,并且您正在浏览所有这些并将它们设置为 DateTime.MinValue,那么您想要放入委托的代码单元究竟是什么?
回答by bytebender
There are always best practices and such but I don't know if I agree with everything that everybody has said...
总是有最佳实践等,但我不知道我是否同意每个人所说的一切......
If I understand you correctly you have to enumerate your nested array for several different reasons and would like to encapsulate that functionality to be reused.. There are several different ways to accomplish but here is one using linq and one with out...
如果我理解正确,您必须出于多种不同的原因枚举您的嵌套数组,并希望封装该功能以供重用。
List<DateTime[]> changes = new List<DateTime[]>();
changes = PopulateChanges();
// *** As pointed out ForEach this will not change the value in the array, Thanks!***
changes.ForEach(change => change.ToList().ForEach(date => date = DateTime.MinValue));
// this how ever works but is kind of confusing...
changes = changes.Select(change => change.Select(date => DateTime.MinValue).ToArray()).ToList();
//Even that would get old writing it over and over again...
I would do it this way...
我会这样做...
private void ForEachOnNestedDates(List<DateTime[]> list, Func<DateTime, DateTime> method)
{
// Use your code...
for (int i = 0; i < list.Count; i++)
{
for(int j = 0; j < list[i].Length; j++)
{
list[i][j] = method.Invoke(list[i][j]);
}
}
}
this would allow you to reuse this and do different things to each item. ex.
这将允许您重用它并对每个项目做不同的事情。前任。
//Add a Day to each datetime value
ForEachOnNestedDates(changes, (DateTime date) => date.AddDays(1));
//You also make it even more readable
ForEachOnNextedDates(changes, DoSomethingWithDate);
private DateTime DoSomethingWithDate(DateTime value)
{
}
this would be used for thing done to each date time as opposed to thing done with each date time... That would be slightly different.
这将用于每个日期时间完成的事情,而不是每个日期时间完成的事情......那会略有不同。