3

現在これでフィルタリングされているダイナミックのリストのリストがあります:

var CPUdataIWant = from s in rawData
                   where s.stat.Contains("CPU")
                   select s;

//CPUDataIWant is a List<List<dynamic>>.

各内部リストに 86000 個の値があります。

そして、私がする必要があるのは、値を3つのグループにグループ化し、そのグループの最大値を選択し、それを動的リストの別のリストに挿入するか、CPUDataIWant.

だから私が欲しいものの例は次のようになります:

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>>

このリストには、A という名前の X 個のリストがあります。A には 86000 個の値があります。ここでは、それらが int であるとしましょう。

私が欲しいのは、持っていることです

List<List<object>>

しかし、A の 86000 の値の代わりに、A の 3 つの値の最大値から作成される 28700 が必要です。

4

4 に答える 4

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);
于 2012-07-26T14:02:07.720 に答える
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");
}
于 2012-07-26T16:04:33.077 に答える
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()
于 2012-07-26T13:56:59.260 に答える
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);
}
于 2012-07-26T14:13:52.417 に答える