C# 如何使用LINQ(整体)分配集合中的属性
我有一个Foo类型的数组或集合,其属性值为double类型。如果我有一个值列表,如何使用LINQ将它们分配给我的集合 基本上我想要的是相反的C# 如何使用LINQ(整体)分配集合中的属性,c#,arrays,linq,C#,Arrays,Linq,我有一个Foo类型的数组或集合,其属性值为double类型。如果我有一个值列表,如何使用LINQ将它们分配给我的集合 基本上我想要的是相反的 var values = list.Select((item)=>item.Value).ToArray(); 示例代码: class Foo { public double Value { get; set; } // many other properties } static void Main() { // ex
var values = list.Select((item)=>item.Value).ToArray();
示例代码:
class Foo
{
public double Value { get; set; }
// many other properties
}
static void Main()
{
// example initializations
var list = new Foo[4];
// somewhere else in the code
var values = GetValues();
// returns { 10.0, 12.0, 15.5, 17.3 }
// Q? Can I do this in LINQ with one statement,
// without re-creating list. I just want to set
// one property of Foo based on my array.
// assign values (I know lengths will match)
for(int i=0; i<list.Length; i++)
{
list[i].Value = values[i];
}
}
但这是可行的,尽管这感觉像是一个乱七八糟的问题
list.Zip(values, (leg, val) => leg.Value=val ).ToArray();
注:这与类似,只是我想分配列表中的所有值,而不仅仅是筛选一个值并获取对它的引用
PS2。如果Foo是一种值类型,这会更难吗
仅供参考。在Fortran中,即使列表是一个数组,也要执行列表%value=值。在Fortran语言中,结构数组同样也是数组结构。朱莉娅,我希望有其他语言的Python?我也这么做了。但是,C类型语言不支持:-这:
var list = values.Select(item =>new Foo{Value=item}).ToArray();
同:
for(int i=0; i<list.Length; i++)
{
list[i].Value = values[i];
}
您可以在列表上使用ForEach
class Program
{
static void Main(string[] args)
{
int[] x = { 1, 2, 3 };
Foo[] y = new Foo[]{ new Foo{Name="a"},new Foo{Name="b"},new Foo{Name="c"}};
int i = 0;
y.ToList().ForEach(a => a.Value = x[i++]);
foreach (Foo f in y)
Console.Out.WriteLine(f.ToString());
//or even ;)
y.ToList().ForEach(a => Console.Out.WriteLine(a.ToString));
}
}
class Foo
{
public int Value { get; set; }
public string Name { get; set; }
public override string ToString()
{
return Name + Value;
}
}
我现在想不出一个办法来摆脱int I=0线
但如果你这样做了,请考虑下面的论点:
编辑:好的,所以有人对不是LINQ的收费表提出了异议。这样做:class Program
{
static void Main(string[] args)
{
int[] x = { 1, 2, 3 };
Foo[] y = new Foo[]{ new Foo{Name="a"},new Foo{Name="b"},new Foo{Name="c"}};
int i = 0;
y.Select(a => a.Value = x[i++]).ToArray();
foreach (Foo f in y)
Console.Out.WriteLine(f.ToString());
}
}
class Foo
{
public int Value { get; set; }
public string Name { get; set; }
public override string ToString()
{
return Name + Value;
}
}
Select是LINQ,ToArray使操作在循环打印值时实际发生。。但这并不是查询系统的预期目的
它的高低是:
问:我如何
A:你不知道
你用的是fortran
答:您编写一个foreach循环,就像其他对生成可读、自解释、可维护的代码感兴趣的人一样您可以创建一个类似LINQ的扩展方法,它不会返回IEnumerable,而是修改传入的结构的IEnumerable或IList
public static class ExtentionMethods
{
public static void Update<TItem, TValue>(this IEnumerable<TItem> @this, IEnumerable<TValue> items, Action<TItem, TValue> applyAction)
where TItem : class
{
using (var thisEnumerator = @this.GetEnumerator())
using (var itemEnumerator = items.GetEnumerator())
{
while (thisEnumerator.MoveNext() && itemEnumerator.MoveNext())
{
applyAction(thisEnumerator.Current, itemEnumerator.Current);
}
}
}
public delegate void UpdateAction<TItem, TValue>(ref TItem item, TValue newValue);
public static void Update<TItem, TValue>(this IList<TItem> @this, IEnumerable<TValue> items, UpdateAction<TItem, TValue> applyAction)
where TItem : struct
{
using (var itemEnumerator = items.GetEnumerator())
{
for (int i = 0; i < @this.Count && itemEnumerator.MoveNext(); i++)
{
var temp = @this[i];
applyAction(ref temp, itemEnumerator.Current);
@this[i] = temp;
}
}
}
}
像
namespace SandboxConsole
{
class Program
{
class Foo
{
public double Value { get; set; }
}
struct Foo2
{
public double Value { get; set; }
}
private static IReadOnlyList<double> GetValues()
{
return new[] { 10.0, 12.0, 15.5, 17.3 };
}
static void Main()
{
// example initializations
var list = new Foo[4];
var list2 = new Foo2[4];
// somewhere else in the code
var values = GetValues();
// returns { 10.0, 12.0, 15.5, 17.3 }
list.Update(values, (item, value) => item.Value = value);
list2.Update(values, (ref Foo2 item, double value) => item.Value = value);
}
}
}
使用Zip将要更新的项与要注入的值配对是很好的,但这就是您应该做的。一旦您将它们配对,您应该在这些对上循环进行更新
var pairs = list.Zip(values, (leg, val) => new { leg, val });
foreach (var pair in pairs)
pair.leg.Value = pair.val;
Linq旨在帮助您查询数据,而不是修改数据。Linq通常是功能性的,它表示查询。您通常不会期望LINQ查询有副作用。就我个人而言,我会坚持某种循环。你们的科学家全神贯注于他们是否能做到,他们没有停下来思考他们是否应该。。。伊恩·马尔科姆博士——我想澄清我编辑的问题。我不想再创造富了。所以没有新的Foo语句。我想为Foo分配值或单个属性,那么最好使用for或foreach循环。要实现foreach,您可以使用var list=values.Selectv,i=>new{Value=v,Index=i}不使用LINQT的方法。对于被否决的人,请告诉我您认为对我的答案没有帮助的地方。op没有寻找实际的LINQ解决方案,因为他不关心list.Zipvalues,leg,val=>leg.Value=val.ToArray的结果;在他的示例中,他只需要一个单行扩展方法,该方法可以执行不会像list.Zipvalues,leg,val=>leg.Value=val.ToArray那样冗长的操作;我想可能是OP把他们都否决了。。不过,提出一个在概念上没有合理答案的问题,然后对所有提出令人费解的胡言乱语的人投反对票,这有点像朗姆酒交易answer@CaiusJard因此,这个故事的寓意是,不要试图发布没有合理答案的问题的答案,不?Servy我认为我的答案是合理的。它真正做的就是把现有的foreach压缩成一个扩展方法。@ScottChamberlain我看不出它比简单地使用循环有什么好处。与这里的其他答案相比,它没有那么糟糕,但它仍然没有真正增加任何价值,而且它仍然有一些成本。到目前为止,Linq的最佳使用。这一点很清楚,因为它比不返回值的Zip语句更能显示意图。此外,延迟执行似乎只执行一个循环。
var pairs = list.Zip(values, (leg, val) => new { leg, val });
foreach (var pair in pairs)
pair.leg.Value = pair.val;