我有两个集合A和B。集合A的所有内容之和应为0(它们具有将其推送到集合A的唯一标识符),而集合B的总和不必为0。例如:< / p>
item1 = 200;
item2 = -200;
item3 = 200
这些不等于0,但是具有相同的唯一ID,现在位于集合A中。我想将它们分组并比较前两个项目,如果它们合计为0,我将移至该组中的下一个项目如果这些项目的总和不为0,我想将其移至集合B。
这就是我现在拥有的:
var grp= colA.AsEnumerable()
.Where(a => a.Field<string>("unique_id") != null)
.GroupBy(b=> b["unique_id"])
.Where(c=> c.Count() > 1).ToList();
foreach(var d in grp)
{
var sum = d.AsEnumerable().Sum(e => e.Field<decimal>("amount"));
}
if(sum != 0){//compare rows in group}
这成功地将不等于0的项目进行了分组,但是我在如何比较item1和item2然后比较item3时陷入了困境,以便可以将item3移至集合B,然后集合A的总和为0。
答案 0 :(得分:1)
这样会帮助您吗?
grp.ForEach(g =>
{
int stepNumber = 0;
int step = 2;
var target = g.Skip(stepNumber * step).Take(step);
if (target.Sum(x => x.Field<decimal>("amount")) != 0)
{
foreach (var item in target.Select(x => x))
{
colA.Rows.Remove(item);
colB.Rows.Add(item);
}
}
stepNumber ++;
});
答案 1 :(得分:0)
如果您使用“跳过/获取”来枚举序列,则将一遍又一遍地从序列的开头开始。这可以做得更聪明!
按以下顺序有点不清楚您想要什么:
200, -200, 10, 11, -11, 12, -12, 13, -13
200和-200留在集合A中。但是,您是否只删除10个,并让A中的对[11,-11],[12,-12],[13,-13]删除? [10,11],[-11,12],[-12,13],-13?
让我们假设您想要后者。您需要将输入序列分成两个对。为此,让我们制作一个可重用的功能。
输入:一系列项目和splitSize 输出:一系列ICollection,其中每个ICollection都具有splitsize(最后一个除外)
因此输入:0 1 2 3 4 5 6 7 8 9和SplitSize 3 输出:[0 1 2] [3 4 5] [6 7 8] [9]
我将其创建为扩展方法,因此可以在LINQ串联中使用它。参见extension methods demystified
public static IEnumerable<IList<TSource>> Split<TSource>(this IEnumerable<TSource> source,
int splitSize)
{
// todo: check for non-null source and positive splitSize
var enumerator = source.GetEnumerator();
while (enumerator.MoveNext())
{
// still elements to process. Create and fill the next splitList
List<TSource> splitList = new List<TSource>(splitSize);
splitList.Add(enumerator.Current()
while (splitList.Count < splitSize && enumerator.MoveNext())
{
// still elements to add:
splitList.Add(enumerator.Current);
}
// if here: either no more elements, or splitList full.
yield return splitList;
}
}
借助此功能,我们可以将输入分为[0 1] [2 3] [4 5]对,并检查它们应属于零和还是非零和的集合:>
void CreateZeroSumCollections<TSource>(IEnumerable<TSource> source,
Func<TSource, int> keySelector,
out IList<TSource> zeroCollection,
out IList<TSource> nonzeroCollection)
{
var zeroCollection = new List<TSource>();
var nonzeroCollection = new List<TSource>();
var splitSource = source.Split(2);
foreach (var splitElement in splitSource)
{
// the splitElement has a length of 2 or less
// Check if the sum is zero
if (splitElement.Count == 2
&& keySelector(splitElement[0]) == -keySelector(splitElement[1])
{ // 2 elements, and sum is zero
zeroCollection.AddRange(splitElement);
}
else
{ // either only 1 element or non zero sum
nonzeroCollection.AddRange(splitElement);
}
}
}
为此,您的序列仅需枚举一次。