Есть ли способ перебрать алфавит в kdb?

Я пишу функцию для выбора всех символов из базы данных, которые начинаются с буквы "A", затем "B", вплоть до буквы "Z". У меня есть фиктивная таблица с 3 символами, которая выглядит следующим образом...

t:([]symbol:`A`App`B`Bapp`C`Capp; price:104.3 124.3 134.2 103.4 402.7 209.8; ID:1 2 3 4 5 6)

наряду с функцией для выбора из таблицы, где символ выглядит как х...

fetch:{[x;y]select from x where symbol like y}

Затем я вызываю функцию для каждого алфавита и добавляю в новую таблицу...

fetchedA:h (`fetch; `t; "A*")
fetchedB:h (`fetch; `t; "B*")
fetchedC:h (`fetch; `t; "C*")

Новая пустая таблица вместе с функцией upsert...

newNormData:([]symbol:`$(); price:`float$(); ID:`int$())
newNorm:{[x] `newNormData upsert x}

h (`newNorm; fetchedA)
h (`newNorm; fetchedB)
h (`newNorm; fetchedC)

Вместо того, чтобы делать 26 вызовов функций для каждого сервера, я хотел бы сделать 1 вызов, который перебирает все символы в алфавите. Как правильно сделать это в kdb/q?

2 ответа

Решение

Переменная.Qa предоставляет список маленьких символов, а.QA - список заглавных символов. Вы можете использовать их для итерации. Есть несколько способов сделать это:

  1. Простая итерация по персонажам и вызов каждого из них. Менее эффективно, поскольку это делает много вызовов RPC.

     q)  fetchAll: raze{h (`fetch; `t;x}) each .Q.A,'"*"
    
  2. Более эффективный, поскольку он делает только 1 вызов RPC. Использование функции "лайк" для альтернативного выбора в шаблоне. Например, ниже команда выберет символы, начинающиеся с A или B.

    Пример: выберите из таблицы, где символ как "[A|B]*"

Ниже команда рассмотрит все символы.

    q)  h(`fetch; `t;"[",("|" sv enlist each .Q.A),"]*")

Также, если ваши таблицы и функции находятся на одном сервере, вам не нужны разные вызовы rpc, чтобы сначала получить данные символов, а затем обновить таблицу newNorm. Вы можете сделать это за один звонок. Один из способов - определить функцию на сервере и вызвать ее.

Функция на сервере:

  q) fetchAndUpdNorm:{[x]`newNormData upsert fetch[t] x}

На клиенте:

  q)  h(`fetchAndUpdNorm;"[",("|" sv enlist each .Q.A),"]*")

Обновление на основе комментариев Джонатона:

Альтернативная команда для второго примера:

 q)  h(`fetch; `t;"[A-Z]*")

Для последнего случая:

 q)  h(`fetchAndUpdNorm;"[A-Z]*")

Я верю, что вы ищете fetch[t] each .Q.A,'"*", Вы можете сделать это и перейти к новой таблице, запустив

h({`newNormData upsert fetch[`t] x;}';.Q.A,'"*")

сторона клиента.

В качестве альтернативы, если вы хотите использовать символы, начинающиеся только с заглавной буквы, и располагать их в алфавитном порядке, выполнить их проще.

newNormData:`symbol xasc select from t where symbol like "[A-Z]*"

вместо.

Другие вопросы по тегам