www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - merging a group result

reply Alex <sascha.orlov gmail.com> writes:
Hi all,
I'm looking for a d-ish way to solve a basic 
"split-apply-combine" workflow. The idea is described (and 
solved) here:

https://stackoverflow.com/questions/39922986/pandas-group-by-and-sum

So, given a structure with some fields, say

´´´
struct S
{
	string s;
	int i;
}
´´´

I create an array of them, like

´´´
void main()
{
         import std.experimental.all;

	S[] sarr;
	sarr.length = 6;
	sarr[0].s = "a";
	sarr[1].s = "a";
	sarr[2].s = "b";
	sarr[3].s = "b";
	sarr[4].s = "c";
	sarr[5].s = "c";
	sarr[0].i = 1;
	sarr[1].i = 2;
	sarr[2].i = 4;
	sarr[3].i = 8;
	sarr[4].i = 16;
	sarr[5].i = 32;
	auto res = sarr.group!((a, b) => a.s == b.s);
         //writeln(res);
}
´´´

I'm also able to group them by a field, see last line.

But now the problems begin:
- The group operation tries to use the structure itself as a key, 
despite I provide a custom binary predicate.
- I could ignore the fact above, but how, given the result of the 
grouping operation I can merge by some function (like sum) the 
group results?

At this moment, I assume, that I'm approaching the problem from 
the wrong end, and simply don't see something trivial... Anyway, 
does anybody has a hint for me?
Jul 23 2018
next sibling parent rikki cattermole <rikki cattermole.co.nz> writes:
On 23/07/2018 11:49 PM, Alex wrote:
 
 At this moment, I assume, that I'm approaching the problem from the 
 wrong end, and simply don't see something trivial... Anyway, does 
 anybody has a hint for me?
Map the range to the integer value, then sum it.
Jul 23 2018
prev sibling parent reply Seb <seb wilzba.ch> writes:
On Monday, 23 July 2018 at 11:49:58 UTC, Alex wrote:
 Hi all,
 I'm looking for a d-ish way to solve a basic 
 "split-apply-combine" workflow. The idea is described (and 
 solved) here:

 https://stackoverflow.com/questions/39922986/pandas-group-by-and-sum

 So, given a structure with some fields, say

 ´´´
 struct S
 {
 	string s;
 	int i;
 }
 ´´´

 I create an array of them, like

 ´´´
 void main()
 {
         import std.experimental.all;

 	S[] sarr;
 	sarr.length = 6;
 	sarr[0].s = "a";
 	sarr[1].s = "a";
 	sarr[2].s = "b";
 	sarr[3].s = "b";
 	sarr[4].s = "c";
 	sarr[5].s = "c";
 	sarr[0].i = 1;
 	sarr[1].i = 2;
 	sarr[2].i = 4;
 	sarr[3].i = 8;
 	sarr[4].i = 16;
 	sarr[5].i = 32;
 	auto res = sarr.group!((a, b) => a.s == b.s);
         //writeln(res);
 }
 ´´´

 I'm also able to group them by a field, see last line.

 But now the problems begin:
 - The group operation tries to use the structure itself as a 
 key, despite I provide a custom binary predicate.
 - I could ignore the fact above, but how, given the result of 
 the grouping operation I can merge by some function (like sum) 
 the group results?

 At this moment, I assume, that I'm approaching the problem from 
 the wrong end, and simply don't see something trivial... 
 Anyway, does anybody has a hint for me?
You could use chunkBy: auto res = sarr.chunkBy!((a, b) => a.s == b.s).map!(a => tuple(a.front.s, a.map!(b => b.i).sum)); https://run.dlang.io/is/TJOEmf chunkBy: --- [S("a", 1), S("a", 2)] [S("b", 4), S("b", 8)] [S("c", 16), S("c", 32)] --- group: --- Tuple!(S, uint)(const(S)("a", 1), 2) Tuple!(S, uint)(const(S)("b", 4), 2) Tuple!(S, uint)(const(S)("c", 16), 2) ---
Jul 23 2018
parent Alex <sascha.orlov gmail.com> writes:
On Monday, 23 July 2018 at 12:07:37 UTC, Seb wrote:
 You could use chunkBy:

 auto res = sarr.chunkBy!((a, b) => a.s == b.s).map!(a => 
 tuple(a.front.s, a.map!(b => b.i).sum));
 https://run.dlang.io/is/TJOEmf
Ha... This helps! Thanks a lot! :)
Jul 23 2018