Starting with
'k v'=. xs
n=. >./k
k2=. 1+i.n
For the second row, the first approach that comes to mind is to treat it as an
association:
v2=. (k i. k2) { v , 0
Then recombine as k2 ,: v2. An alternative, slightly less nice, is to add the
requisite number of zeroes onto the end and then sort:
missing=. k2 -. k
v2=. (k , missing) /: (v , (#missing)#0)
Or recombine before sorting:
xs2=. /:~&.|: (k , missing) ,: (v , (#missing)#0)
Your idea to combine with an existing bed of zeroes is workable too; don't use
take and drop, though, but amend:
v2=. v (k-1)} n#0
(The k-1 being necessary only because your indices start at 1.)
Or, use a complex left argument to # to pad the result with zeroes in the
appropriate places:
v2=. (1 j. _1 + 2 -~/\ 0,k) # v
Though this has one pitfall: it doesn't work if there is a gap at the
_beginning_ of k (e.g., the first element is 2 rather than 1), because the
padding is added after the replicated element.
How did you end up with this array in the first place? It looks a bit like a
histogram showing how frequently some event happened on each day of the month.
Assuming so, there is a trick to avoid the problem in the first place.
Consider the following example histogram (only going up to 7 for brevity, and
starting from zero rather than one out of sensibility):
a=. 0 0 0 1 1 3 6 6 6 6
#/.~ a
3 2 1 4
Here 2, 4, and 5 didn't show up in the histogram, even though we would like to
know that they appeared zero times. The solution is to add one of each
element we are interested in, and then subtract it after:
_1 + #/.~ (i.7) , a
3 2 0 1 0 0 4
Prepending i.7 rather than appending it also ensures that the result histogram
comes out in order, even if a happened not to be.
-E
Sun, 23 Jul 2023, Fr. Daniel Gregoire wrote:
Hi!
(Apologies if this is a double-post, I believe I sent it before I was
officially on the mailing list, and I don't see it in the archives).
Given:
|:xs
1 23
2 4
3 5
4 10
5 397
6 3
7 190
8 44
9 4
10 5
11 13
12 1011
13 10
14 1119
15 72
16 1
17 1
19 6
21 3
22 2
23 1
26 2
28 2
29 2
30 1
31 2
I'd like $xs to be 2 31 but you can see that 18, 20, 24, 25, and 27
are "missing".
I'd like to "fill the holes" so the first row of xs is all the
integers 1 through 31 sequentially, and to put corresponding zeros in
the second row where I've filled the holes in the first.
My thoughts have centered around using (1+i.31),.31#0 to have a 2 by
31 array with all zeros in the second row, and then shifting my
original to find the non-sequential parts with something like:
(1|.{.xs) - {.xs
But then I'm struggling to reason about a non-loopy way to put it all
together. Any help is greatly appreciated.
Kind regards,
Daniel
----------------------------------------------------------------------
For information about J forums see http://www.jsoftware.com/forums.htm
----------------------------------------------------------------------
For information about J forums see http://www.jsoftware.com/forums.htm