如何中断kdb中的“循环”?

时间:2018-06-19 22:43:52

标签: kdb

numb是数字列表:

q))input
42 58 74 51 63 23 41 40 43 16 64 29 35 37 30 3  34 33 25 14 4  39 66 49 69 13..

31 41 39 27 9  21 7  25 34 52 60 13 43 71 10 42 19 30 46 50 17 33 44 28 3  62..

15 57 4  55 3  28 14 21 35 29 52 1  50 10 39 70 43 53 46 68 40 27 13 69 20 49..

3  34 11 53 6  5  48 51 39 75 44 32 43 23 30 15 19 62 64 69 38 29 22 70 28 40..

18 30 60 56 12 3  47 46 63 19 59 34 69 65 26 61 50 67 8  71 70 44 39 16 29 45..

我想遍历每一行并计算前2个数字,然后是3个数字,然后是4个数字的总和,等等。如果该总和大于1000,我想在该特定行上停止迭代并跳到下一行并做同样的事情。这是我的代码:

{[input]
 tot::tot+{[x;y]
   if[1000<sum x;:count x;x,y]
  }/[input;input]
 }each numb 

我的问题是在将x的计数添加到tot之后,over继续在同一行上。如何退出over并跳到下一行?

更新:(问题仍然存在)我很感谢到目前为止的所有回答,但是我并不是在寻找一种将前n个数字相加的有效方法。我的问题是如何打破over并跳到下一行。我想实现与那些小型脚本相同的功能:

C ++

for (int i = 0; i <= 100; i++) {
if (i = 50) { printf("for loop exited at: %i ", i); break; }
}

Python

for i in range(100):
  if i == 50:
      print(i);
      break;

R

for(i in 1:100){
  if(i == 50){
    print(i)
    break
  }
}

4 个答案:

答案 0 :(得分:1)

我认为这就是您要实现的目标。

sum {(x & sums y) ? x}[1000] each input

它获取每一行的累加总和,并在该总和与输入限制之间取一个元素明智的最小值,从而将输出限制为如下限制:

q)(100 & sums 40 43 16 64 29)
40 83 99 100 100

然后使用?运算符以查找该限制的第一个出现位置(即等于或超过此限制的元素),因为索引为0会加上一个。在示例中,前100个出现在3个元素之后。您可能希望添加一个,以便将第一个元素包括在计数限制内。

q)40 83 99 100 100 ? 100
3

然后对输入的所有行求和。

答案 1 :(得分:1)

在这种情况下,如果您不满足条件,则可以使用承保范围退出 https://code.kx.com/q/ref/adverbs/#converge-repeat

第一个参数将是一个基于x的当前值进行检查的函数,该值将是要在主函数中传递的下一个值。

在您的示例中,我使用主输入线进行了投影,然后每次增加我所求和的索引:

q)numb
98 11 42 97 89 80 73 35 4  30
86 33 38 86 26 15 83 71 21 22
23 43 41 80 56 11 22 28 47 57
q){[input] {x+1}/[{100>sum (y+1)#x}[input;];0] }each numb
1 1 2

这将返回运行总和超过100的每个索引的第一个索引

但是,这并不是KDB的理想用例 可以用类似的方法完成

(sums@/:numb) binr\: 100

也许您的真实例子更有意义

答案 2 :(得分:1)

您可以在KDB中使用while循环,尽管所有KDB开发人员通常都太害怕公开嘲笑和嘲笑这样做

Unhandled Exception: System.InvalidOperationException: The security identifier is not 
allowed to be the owner of this object.
at System.Security.AccessControl.NativeObjectSecurity.Persist(String name, SafeHandle 
   handle, 
   AccessControlSections includeSections, Object exceptionContext)
at System.Security.AccessControl.NativeObjectSecurity.Persist(String name, 
   AccessControlSections includeSections, Object exceptionContext)
at System.Security.AccessControl.NativeObjectSecurity.Persist(String name, 
   AccessControlSections includeSections)
at System.Security.AccessControl.FileSystemSecurity.Persist(String fullPath)
at System.IO.File.SetAccessControl(String path, FileSecurity fileSecurity)
at rtest.Program.Main(String[] args) in C:\somepath\Program.cs:line 52

答案 3 :(得分:0)

Kdb确实具有“停止循环”机制,但仅在具有单个种子值的单子函数的情况下

/keep squaring until number is no longer less than 1000, starting at 2
q){x*x}/[{x<1000};2]
65536

/keep dealing random numbers under 20 until you get an 18 (seed value 0 is irrelevant)
q){first 1?20}\[18<>;0]
0 19 17 12 15 10 18

但是,这并不完全适合您的用例,正如其他人指出的那样,这不是您将/应该在kdb中解决此问题的方式。