gpt4 book ai didi

c# - 如何根据对象属性的总和获取 List 项的子集

转载 作者:行者123 更新时间:2023-11-30 13:16:26 24 4
gpt4 key购买 nike

我想根据其中一个对象属性的值从列表中获取对象子集,特别是我想根据该属性的聚合值之和获取前几个对象。

我可以手动遍历列表,添加/求和属性的值并将结果与​​我想要的值进行比较,但是有更好的方法吗?

例如,假设我有这个列表:

List<MyObj> MyObjList;

MyObj 看起来像这样:

public class MyObj
{
public int MyValue { get; set; }
}

MyObjList 具有以下对象和值,顺序如下:

MyObjList[0].MyValue = 1;
MyObjList[1].MyValue = 3;
MyObjList[2].MyValue = 2;
MyObjList[3].MyValue = 3;
MyObjList[4].MyValue = 2;

例如,我可能想要获取前几个项目,其中 MyValue 的总和 <= 5,这将仅返回前 2 个对象。

你会怎么做?

最佳答案

你要的是Aggregate和TakeWhile的组合,那就这么写吧。

public static IEnumerable<S> AggregatingTakeWhile<S, A>(
this IEnumerable<S> items,
A initial,
Func<A, S, A> accumulator,
Func<A, S, bool> predicate)
{
A current = initial;
foreach(S item in items)
{
current = accumulator(current, item);
if (!predicate(current, item))
break;
yield return item;
}
}

现在你可以说

var items = myObjList.AggregatingTakeWhile(
0,
(a, s) => a + s.MyValue,
(a, s) => a <= 5);

请注意,我已决定在累加器更新后查询谓词;根据您的应用,您可能需要稍微调整一下。

另一种解决方案是将聚合与枚举相结合:

public static IEnumerable<(A, S)> RunningAggregate<S, A>(
this IEnumerable<S> items,
A initial,
Func<A, S, A> accumulator)
{
A current = initial;
foreach(S item in items)
{
current = accumulator(current, item);
yield return (current, item);
}
}

现在你想要的操作是

var result = myObjList
.RunningAggregate(0, (a, s) => a + s.MyValue)
.TakeWhile( ((a, s)) => a <= 5)
.Select(((a, s)) => s);

我可能在那里弄​​错了元组语法;我现在手边没有 Visual Studio。但是你明白了。聚合产生一个(sum,item)元组序列,现在我们可以在那个东西上使用普通的序列运算符。

关于c# - 如何根据对象属性的总和获取 List<T> 项的子集,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47211254/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com