Distribute elements of one list over elements of another list
Clash Royale CLAN TAG#URR8PPP
Distribute elements of one list over elements of another list
I have two lists:
l1:`a`b`c;
l2: til 20;
I am trying to create a dictionary 'd' that contains the elements of 'l1' as key and the elements of 'l2' evenly distributed over it. So like this:
d:(`a`b`c)!(0j, 3j, 6j, 9j, 12j, 15j, 18j;1j, 4j, 7j, 10j, 13j, 16j, 19j;2j, 5j, 8j, 11j, 14j, 17j)
The order of the elements is not relevant, I just need them balanced. I was able to achieve that in an iterative way (happy to add the code, if that's considered helpful), but there must be a more elegant way (potentially with adverbs?).
2 Answers
2
It can be done using the group
:
group
q)group (count[l2]#l1)
(`a`b`c)!(0j, 3j, 6j, 9j, 12j, 15j, 18j;1j, 4j, 7j, 10j, 13j, 16j, 19j;2j, 5j, 8j, 11j, 14j, 17j)
If your l2
is something else instead of til 20
, then you have to lookup the items back after grouping :
l2
til 20
q)l2: 20#.Q.a
q)l2
"abcdefghijklmnopqrst"
q)l2 group (count[l2]#l1) // lookup the items back from l2 after grouping
(`a`b`c)!("adgjmps";"behknqt";"cfilor")
You can use the reshape functionality of the take operator #
. It takes two arguments: a LHS of at least 2 dimensions and the list to reshape.
#
For example (3;4)#til 12
will reshape the list 0 1 ... 12
into a 3 by 4 matrix
(3;4)#til 12
0 1 ... 12
In our case, the number of the number of elements in l1
will will not necessary divide exactly into the number of elements in l2
(we don't want a rectangular matrix). Instead we can supply a null as the second dimension which will take care of distributing the remainders.
l1
l2
q) l1!(count[l1];0N)#l2
a| 0 1 2 3 4 5
b| 6 7 8 9 10 11 12
c| 13 14 15 16 17 18 19
This method performs very well for larger input lists.
As a side note, when using .Q.fc
to split a vector argument over n
slaves for multi-threading, kdb uses the #
operator to reshape the vector into n
vectors, one for each slave.
.Q.fc
n
#
n
By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.