KDB/Q: як пятля без завес?

Я вучуся д на базе КДБ. Я занепакоены тым фактам, што няма ніякіх завес ў в. Мне трэба напісаць алгарытм, які я хацеў бы напісаць з некалькімі укладзенымі для завес ў шматслоўным праграме, як C. Але ў в я затрымаўся на тым, што я не магу цыкл.

Проста каб даць канкрэтны прыклад (адзін з многіх), у мяне ёсць гэты просты вектар (слупок табліцы):

q)closures
price
-----
18.54
18.53
18.53
18.52
18.57
18.9 
18.9 
18.77
18.59
18.51
18.37

Мне патрэбен вектар, групы 3by3 гэтыя запісы з накладаннем, як (з дапамогай сінтаксісу R): замкі [0: 2], замкі [1: 3], замкі [2: 4], замкі [3: 5] ... Як я магу зрабіць?

Увогуле, як мне трэба змяніць свой менталітэт, каб правільна праграмаваць ў в?

Вялікі дзякуй за вашы прапановы Marco

8
Гэта не праўда, што д не мае завес, гэта проста, што вы не рэкамендуецца выкарыстоўваць іх, калі вы сапраўды не павінны. Ёсць некаторыя выпадкі, калі з дапамогай цыкла з'яўляецца абсалютна правільным, што трэба зрабіць, і што вы хацелі б праверыць , а і зрабіць ключавыя словы.
дададзена аўтар mollmerx, крыніца

7 адказы

Звяртаючыся ваш апошні пункт аб «як мне трэба, каб змяніць свой менталітэт, каб правільна праграмаваць ў в?»:

Вы павінны выкарыстоўваць больш (/), сканаванне (\) і .z.s, а не з дапамогай завес.

Напрыклад, ваша праблема можа быць вырашана наступным чынам: (Звярніце ўвагу, што гэта не будзе фактычна лепшыя рашэнні для вашай канкрэтнай праблемы - індэксаванне падыход лепш там, - але тым не менш гэтыя рашэнні ніжэй, павінны дапамагчы атрымаць кропку ў папярочніку)

price:18.54 18.53 18.53 18.52 18.57 18.9 18.9 18.77 18.59 18.51 18.37

q)3#'{1_x}\[8;price]
18.54 18.53 18.53
18.53 18.53 18.52
18.53 18.52 18.57
18.52 18.57 18.9
18.57 18.9  18.9
18.9  18.9  18.77
18.9  18.77 18.59
18.77 18.59 18.51
18.59 18.51 18.37

г.зн. ітэрацыя па спісе, здрабніць адзін ад кожнага часу, прымаць першыя 3 кожную ітэрацыю

або аналагічным

q)3#'{1 rotate x}\[8;price]
18.54 18.53 18.53
18.53 18.53 18.52
18.53 18.52 18.57
18.52 18.57 18.9
18.57 18.9  18.9
18.9  18.9  18.77
18.9  18.77 18.59
18.77 18.59 18.51
18.59 18.51 18.37

г.зн. кручэнне 1 восем разоў, прымае першыя 3 кожнае кручэнне

Выкарыстанне .z.s падыходу

q){$[2

гэта значыць, калі ёсць, па меншай меры, 3 элементы злева, прымаюць першыя 3, затым адсекчы першы элемент і паўторна ўжыць тую ж функцыю ў скарочаным спісе.

Выкарыстанне больш чым (/) будзе згорнуты ў гэтым прыкладзе, але ў цэлым за кадрам з'яўляецца для замены жылыя «а» тыпу канструкцый

i:0
a:0;
while[i<10;i+:1;a+:10] 

лепш дасягаецца з дапамогай

q){x+10}/[10;0]
100

г.зн. дадаць 10, у дзесяць разоў з пачатковым значэннем (насення) ад нуля.

b:();  
while[not 18~last b;b,:1?20]      

г.зн. трымаць даданне выпадковых лікаў ад 1 да 20, пакуль вы не націснеце 18, а затым спыніцца.

лепш дасягаецца з дапамогай

q){x,1?20}/[{not 18~last x};()]
1 2 16 5 8 18

гэта значыць дадаць выпадковы лік у дыяпазоне ад 1 да 20, ітэрацыі да таго часу, пакуль функцыя праверкі вяртае ісціну, пачынаць з() у якасці пачатковага значэння

Ёсць шмат іншых варыянтаў для выкарыстання сканавання і больш, у залежнасці ад таго, ці выкарыстоўваецца функцыя вы ітэрацыі з'яўляецца монадическим/Диадическим і г.д.

Як шырокае абагульненне: А «пры г = 1: 10» завесы тыпу можа быць дасягнута з выкарыстаннем «д функцыі кожнага г», «Зрабіце» пятля тыпу можа быць дасягнута з выкарыстаннем «д Функцыя/[numOfTimes; затравочной]», А «а» пятля тыпу можа быць дасягнута з дапамогай Q «функцыі/[booleanCheckFunction; насеньне]»

10
дададзена

Q мае традыцыйныя цыклічныя канструкцыі: зрабіць паўтарыць заяву зададзенага ліку раз і у той час паўтарыць, пакуль гэтая ўмова выканана. Акрамя таго, Q "прыслоўі" кожны , над і г.д. дазволіць вам "пятля" функцыя над элементамі вектара.

Аднак, каб узяць поўнае перавага магутнасці в вы павінны даведацца, як пазбегнуць відавочных завес.

Спрашчаючы свой канкрэтны прыклад (выкарыстоўваць просты вектар, а не табліца 1-слупка), вось як вы можаце перагрупаваць вектар коштаў:

q)price:18.54 18.53 18.53 18.52 18.57 18.9 18.9 18.77 18.59 18.51 18.37
q)2_flip(prev x;x:prev x;x:price)
18.54 18.53 18.53
18.53 18.53 18.52
18.53 18.52 18.57
18.52 18.57 18.9
18.57 18.9  18.9
18.9  18.9  18.77
18.9  18.77 18.59
18.77 18.59 18.51
18.59 18.51 18.37

Вось як гэта працуе. (Памятаеце: • ацэнку справа налева.) У папярэдняя зрухі функцыі цэны справа ў вектары (папярэднічаючы нулявыя значэнні ў пачатку і адкідвання апошняга значэння:

q)prev price
0n 18.54 18.53 18.53 18.52 18.57 18.9 18.9 18.77 18.59 18.51
q)prev prev price
0n 0n 18.54 18.53 18.53 18.52 18.57 18.9 18.9 18.77 18.59

Мы аб'яднаем арыгінальны вектар коштаў з двума ссунуты ў $ 3 \ раз п $ матрыцы. Стоўбцы гэтай матрыцы з'яўляюцца тымі групамі, якія мы хочам. пераварочваць функцыю Транспанаванне матрыцы так, што вы атрымаеце групы ў выглядзе радкоў і нарэшце, мы апускаем першыя два радкі, якія змяшчаюць нулявыя значэнні, выкарыстоўваючы _ аператар.

4
дададзена
@ Вай-ха-Лі: Гэта адказ на канкрэтнае пытанне аб тым, як цэны групы без цыклу. Што я прапусціў?
дададзена аўтар Alexander Belopolsky, крыніца
Гэта не дае адказ на гэтае пытанне. Для таго, каб крытыкаваць або запытаць у аўтара, пакіньце каментар ніжэй свой пост.
дададзена аўтар Wai Ha Lee, крыніца
Ваш адказ заявіў, без тлумачэння прычын і можа быць класіфікаваны як толькі код, які азначае, што яго карыснасць абмежаваная да вырашэння канкрэтнай праблемы пад руку. З каментарамі/тлумачэннем, адказам з'яўляецца значна больш карысным для грамадства ў цэлым.
дададзена аўтар Wai Ha Lee, крыніца
Aha - дзякуй - гэта ацаніў.
дададзена аўтар Wai Ha Lee, крыніца

Адзін метад павінен быў бы вылічыць індэксы, вы клапоціцеся о, а затым індэкс ў масіве -

q) f:{y til[x]+/:neg[x]_til count y}//[x] = sublist length [y] = list
q) f[3;18.54 18.53 18.53 18.52 18.57 18.9 18.9 18.77 18.59 18.51 18.37]
    18.54 18.53 18.53
    18.53 18.53 18.52
    18.53 18.52 18.57
    18.52 18.57 18.9
    18.57 18.9  18.9
    18.9  18.9  18.77
    18.9  18.77 18.59
    18.77 18.59 18.51
3
дададзена
Крута. Я меў {х фліп Сезам [у] + \: Сезам, кол [х] -y-1}
дададзена аўтар Chromozorz, крыніца
flip (-2_price;-1_1_price;2_price)

Як ужо згадвалася, выкарыстоўваючы убудаваныя каманды заўсёды хутчэй, чым ітэрацыі з 'ці /. Вось чаму на Vecor 1 мільён элементаў кода з верхняга адказу займае назаўжды, каб скончыць і выкарыстоўвае ГЗ кучы. Метад індэксацыі ад JPC і Harshal на мілі хутчэй, але адваротны вышэй у тры разы хутчэй, па-ранейшаму.

Калі ў вас ёсць дадзеныя ў фармаце вам трэба проста выкарыстоўваць кожны ўжываць ваша закрыццё спісе элементаў.

Заўсёды трымаць вочы на ​​тое, што \ т кажа вам, гэта добрая практыка - KDB не будзе нічога аптымізаваць для вас.

3
дададзена

Што тычыцца ўкладзеных цыклаў нешта я знайшоў карысным з'яўляецца стварэнне крос спісу. напрыклад

`Для г = 1: 10

 for j=1:20
    for k=1:30
      f(i, j, k)

`

ў в вы можаце

il: 1 _til 11
jl: 1_til 21
kl: 1_til 31
lst: il cross jl cross kl
raze g(x) each til count ls

дзе г вызначаецца як

g: {[i]
itr: first lst[i];
jtr: first 1_lst[i];
ktr: last lst[i];

f(itr, jtr, ktr)
}

Спадзяюся, што гэта растлумачвае. Што тычыцца укупорочные часткі не ведаю сінтаксіс R ёсць. Можа дапамагчы, калі вы можаце сказаць, што вывад, які вы хочаце.

2
дададзена
гэта павінна вырашыць гэтую праблему для вас. <�Код> {[х, у] 3 # ў _ х} [(1 2 3 4 5 6 7 8 9)] кожны Сезам 7
дададзена аўтар Naveen Sharma, крыніца
У пазначэннях R, напрыклад, [1: 3] азначае, што вектар (1,2,3). Так што я меў на ўвазе, што я хацеў, каб гэтая выснова (з вектарныя «закрыцця», як паказана вышэй): 18,53 18,53 18,54 18,52 18,57 18,9 18,9 18,77 18,59 18,51 18,37
дададзена аўтар Marco Mene, крыніца
У пазначэннях R, напрыклад, [1: 3] азначае, што вектар (1,2,3). Так што я меў на ўвазе, што я хацеў, каб гэтая выснова (з вектарныя «закрыцця», як паказана вышэй): (18,54 18,53 18,53) (18,53 18,53 18,52) (18,53 18,52 18,57) ....... ёсць (закаркаванні [0] [1 закрытыя ўчасткі ] замкі [2]) (замкі [1] замкі [2] замкі [3]) (замкі [2] замкі [3] замкі [4]) ...... у любым выпадку я вырашыў часова праблему з дапамогай водную падчас цыкла , Але гэта выглядае так innatural ў в. Я проста думаю, што я знаходжуся на няправільным шляху з мэнтальных падыходам
дададзена аўтар Marco Mene, крыніца

KDB Q з'яўляецца мовай вектарнай апрацоўкі, гэта сіла заключаецца ў апрацоўцы спісы у адрозненні ад апрацоўкі асобнага атамы , як рэгулярна робіцца ў ўладных мовах.

Аднак, у выпадку, калі вы не ведаеце, Q мае падтрымку завес і можа быць выкарыстана ў тых выпадках, калі яны, здаецца, няма іншага шляху! Вось прыклад, які я напісаў у той час як я пачаў міграваць з Java ў KDB Q

isPrime:{[num] i:2; flag:1b; while[i<=sqrt num; if[(num mod i)~0;flag:0b];i:i+1]; flag}

Яна таксама мае рабіць, пакуль цікавае сінтаксіс

    i : 0;
    do [5;
       //Iterated action involving i
        0N!i; //printing i
        i : i + 1
    ];

Have a look here

2
дададзена

Як і некаторыя з вышэйзгаданых карыстальнікаў прапанавалі, я думаю, што лепш думаць, каб зрабіць тут Calculat індэксаў, якія вы хочаце. Калі гэта магчыма, пазбегнуць лямбда і выкарыстоўваць аператары (лепш стыль).

 q)v:18.54 18.53 18.53 18.52 18.57 18.9 18.9 18.77 18.59 18.51 18.37
 q)v (0 1 2)+/:til count v ///generate a list of indices from 0 to the count of v, then add 0 1 2 to each of those indices
18.54 18.53 18.53
18.53 18.53 18.52
18.53 18.52 18.57
18.52 18.57 18.9
18.57 18.9  18.9
18.9  18.9  18.77
18.9  18.77 18.59
18.77 18.59 18.51
18.59 18.51 18.37
18.51 18.37
18.37
0
дададзена