Reputation: 19466
Let's say I have a range 3 < x < 5
.
What's the cleanest way to get 1
if x > 5
, -1
if x < 3
and 0
if it's in the range 3 <x <5
?
I'm trying to mix together &
and |
(trying to adapt the answer from here: In KDB/Q, how do I clip numbers to be in the range -1, 1?). I'm not sure if it's possible this way though.
Upvotes: 2
Views: 321
Reputation: 3179
Another option:
q){$[x<3;-1;x>5;1;0]}each til 10
-1 -1 -1 0 0 0 1 1 1 1
Upvotes: 1
Reputation: 579
As an aside Sean and Rian's answers using bin
are faster than using conditional evaluation - however in this context its already "fast". For readability's sake I would select the conditional evaluation due to how clear and easy it is to read, understand and modify the conditions and returns.
q)\t:10000 {[range;x] (range + 1 0) bin x}[3 5;-50+til 100]
11
q)\t:10000 3 6 bin -50+til 100
10
q)\t:10000 {$[x<3;-1;x>5;1;0]}'[-50+til 100]
75
Upvotes: 0
Reputation: 3651
You could look at a step dictionary which can be used in many places:
q)(`s#-0W 3 6!-1 0 1) til 10
-1 -1 -1 0 0 0 1 1 1 1
Or fill the base case:
q)-1^(`s#3 6!0 1) til 10
-1 -1 -1 0 0 0 1 1 1 1
Even better here for your exact question is to go direct to using bin:
q)3 6 bin til 10
-1 -1 -1 0 0 0 1 1 1 1
Upvotes: 3
Reputation: 1593
You could adapt the bin
keyword which does something like what you're looking for out of the box:
q)3 5 bin 0 1 2 3 4 5 6
-1 -1 -1 0 0 1 1
If you are looking for 0
to be returned for n where x < n < y
then I think you may be able to do something like:
q)f:{[range;x] (range + 1 0) bin x}
q)range35:f[3 5;]
q)range35 0N!til 10
0 1 2 3 4 5 6 7 8 9
-1 -1 -1 -1 0 1 1 1 1 1
Which returns a 0 for the number 4
Upvotes: 4