Сейчас код написан немного итеративно, но хочется как-нибудь его улучшить.
Задача сгруппировать по полю Name при этом все значения создаются с одним и тем же экземпляром (используется первый).
Также мне нужно суммировать все X и Y в этих группах.
Есть идеи получше ?
Заранее спасибо.
using System;
using System.Collections.Generic;
using System.Linq;
class Outer
{
public int A;
}
class WithName
{
public string Name;
}
class Id
{
public int I;
}
class State
{
public int X;
public int Y;
}
class ResultWithName
{
public int SumX;
public int SumY;
public readonly WithName WithName;
public ResultWithName(WithName withName)
{
WithName = withName;
}
}
public class Program
{
public static void Main()
{
var values = TestValues();
var result = new Dictionary<Outer, Dictionary<string, ResultWithName>>();
foreach (var kv in values)
{
var innerValues = kv.Value;
Dictionary<string, ResultWithName> nameGroup;
if (!result.TryGetValue(kv.Key, out nameGroup))
{
nameGroup = result[kv.Key] = new Dictionary<string, ResultWithName>();
}
foreach (var innerKv in innerValues.GroupBy(p => p.Key.Name))
{
var withName = (WithName)null;
foreach (var state in
from w in innerKv
from idStates in w.Value
from state in idStates.Value
select state)
{
// Use first name
if (withName == null) withName = innerKv.First().Key;
var localWithName = withName;
ResultWithName resultWithName;
if (!nameGroup.TryGetValue(innerKv.Key, out resultWithName))
{
resultWithName = nameGroup[innerKv.Key] = new ResultWithName(localWithName);
}
resultWithName.SumX += state.X;
resultWithName.SumY += state.Y;
}
}
}
Console.ReadKey();
}
private static Dictionary<Outer, Dictionary<WithName, Dictionary<Id, List<State>>>> TestValues()
{
return new Dictionary<Outer, Dictionary<WithName, Dictionary<Id, List<State>>>>
{
{
new Outer {A = 1},
new Dictionary<WithName, Dictionary<Id, List<State>>>
{
{
new WithName {Name = "2"},
new Dictionary<Id, List<State>>
{
{
new Id {I = 3},
new List<State>
{
new State {X = 1, Y = 2},
new State {X = 3, Y = 4},
new State {X = 5, Y = 6},
}
},
{
new Id {I = 4},
new List<State>
{
new State {X = 11, Y = 22},
new State {X = 31, Y = 24},
new State {X = 51, Y = 26},
}
},
}
},
{
new WithName {Name = "20"},
new Dictionary<Id, List<State>>
{
{
new Id {I = 3},
new List<State>
{
new State {X = 6, Y = 1},
new State {X = 7, Y = 3},
new State {X = 8, Y = 9},
}
},
{
new Id {I = 4},
new List<State>
{
new State {X = 11, Y = 22},
new State {X = 31, Y = 24},
new State {X = 51, Y = 26},
}
},
}
},
}
}
};
}
}
Здравствуйте, _NN_, Вы писали:
далеко не претендует на хороший вариант,но если немного поправишь под себя
может получишь поаккуратнее
var res = from x in innerValues
group x by x.Key.Name
into gr
from y in gr
from q in y.Value
let f = gr.First()
select new { key = gr.Key, first = f, X = q.Value.Sum(s => s.X), Y = q.Value.Sum(s => s.Y) }
into tmp
group tmp by tmp.key
into ww
select new { firstObj = ww.First().first, sumX = ww.Sum(s => s.X), sumY = ww.Sum(s => s.Y) };
да можно было подумать и написать лучше
,но это первое что в голову стукнуло
Здравствуйте, codenet, Вы писали:
C>да можно было подумать и написать лучше ,но это первое что в голову стукнуло
Боюсь переписывать уже не буду, сейчас работает и этого достаточно.
Только если логику придется менять.
Если есть желание и возможность буду рад если получится упростить код.