我有一个动态列表列表,目前正在通过它进行过滤:
var CPUdataIWant = from s in rawData
where s.stat.Contains("CPU")
select s;
//CPUDataIWant is a List<List<dynamic>>.
我在每个内部列表中都有86000个值。
我需要做的是将值组合成3个组,选择该组的最大值,然后将其插入另一个动态列表列表中,或者只将其从CPUDataIWant
中过滤掉。< / p>
所以我想要的一个例子是:
Raw data = 14,5,7,123,5,1,43,87,9
我的处理价值是:
ProceData = [14,5,7], [123,5,1], [43,87,9]
ProceData = [14,123,87]
不一定要使用linq,但越容易越好。
编辑:好的,我解释了一个想要的东西。这就是我所拥有的:
List<List<object>>
在此列表中,我将列出X个名为A的列表。 在A中我将有86000个值,让我们说它们现在是整数。
我想要的是
List<List<object>>
但是A中没有86000个值,我想要28700,这将取自A中每3个值的最大值。
答案 0 :(得分:0)
这应该会产生预期的结果:
var data = new List<dynamic> { 1, 2, 3, 3, 10, 1, 5, 2, 8 };
var firsts = data.Where((x, i) => i % 3 == 0);
var seconds = data.Where((x, i) => (i + 2) % 3 == 0);
var thirds = data.Where((x, i) => (i + 1) % 3 == 0);
var list = firsts.Zip(
seconds.Zip(
thirds, (x, y) => Math.Max(x, y)
),
(x, y) => Math.Max(x, y)
).ToList();
列表现在包含:
3, 10, 8
或推广到扩展方法:
public static IEnumerable<T> ReduceN<T>(this IEnumerable<T> values, Func<T, T, T> map, int N)
{
int counter = 0;
T previous = default(T);
foreach (T item in values)
{
counter++;
if (counter == 1)
{
previous = item;
}
else if (counter == N)
{
yield return map(previous, item);
counter = 0;
}
else
{
previous = map(previous, item);
}
}
if (counter != 0)
{
yield return previous;
}
}
像这样使用:
data.ReduceN(Math.Max, 3).ToList()
答案 1 :(得分:0)
IEnumerable<int> filtered = raw.Select((x, i) => new { Index = i, Value = x }).
GroupBy(x => x.Index / 3).
Select(x => x.Max(v => v.Value));
或者,如果您打算更频繁地使用它
public static IEnumerable<int> SelectMaxOfEvery(this IEnumerable<int> source, int n)
{
int i = 0;
int currentMax = 0;
foreach (int d in source)
{
if (i++ == 0)
currentMax = d;
else
currentMax = Math.Max(d, currentMax);
if (i == n)
{
i = 0;
yield return currentMax;
}
}
if (i > 0)
yield return currentMax;
}
//...
IEnumerable<int> filtered = raw.SelectMaxOfEvery(3);
答案 2 :(得分:0)
老式的做事方式使其变得非常简单(虽然它不像LINQ那样紧凑):
// Based on this spec: "CPUDataIWant is a List<List<dynamic>>"
// and on the example, which states that the contents are numbers.
//
List<List<dynamic>> filteredList = new List<List<dynamic>>();
foreach (List<dynamic> innerList in CPUDataIWant)
{
List<dynamic> innerFiltered = new List<dynamic>();
// if elements are not in multiples of 3, the last one or two won't be checked.
for (int i = 0; i < innerList.Count; i += 3)
{
if(innerList[i+1] > innerList[i])
if(innerList[i+2] > innerList[i+1])
innerFiltered.Add(innerList[i+2]);
else
innerFiltered.Add(innerList[i+1]);
else
innerFiltered.Add(innerList[i]);
}
filteredList.Add(innerFiltered);
}
答案 3 :(得分:0)
如果您觉得需要使用Aggregate,可以这样做:
(用LinqPad测试)
class Holder
{
public dynamic max = null;
public int count = 0;
}
void Main()
{
var data = new List<dynamic>
{new { x = 1 }, new { x = 2 }, new { x = 3 },
new { x = 3 }, new { x = 10}, new { x = 1 },
new { x = 5 }, new { x = 2 }, new { x = 1 },
new { x = 1 }, new { x = 9 }, new { x = 3 },
new { x = 11}, new { x = 10}, new { x = 1 },
new { x = 5 }, new { x = 2 }, new { x = 12 }};
var x = data.Aggregate(
new LinkedList<Holder>(),
(holdList,inItem) =>
{
if ((holdList.Last == null) || (holdList.Last.Value.count == 3))
{
holdList.AddLast(new Holder { max = inItem, count = 1});
}
else
{
if (holdList.Last.Value.max.x < inItem.x)
holdList.Last.Value.max = inItem;
holdList.Last.Value.count++;
}
return holdList;
},
(holdList) => { return holdList.Select((h) => h.max );} );
x.Dump("We expect 3,10,5,9,11,12");
}