Skip to content

Latest commit

 

History

History
343 lines (241 loc) · 17.7 KB

program.md

File metadata and controls

343 lines (241 loc) · 17.7 KB

<- На головну Розділ

Програмні конструкції

До цих пір ми ввели всі частини мови, які дозволяють нам витягувати дані з вхідного JSON-документа, об'єднувати дані за допомогою рядкових і числових операторів і форматувати структуру вихідного документа JSON. Тим не менше JSONata можна використовувати як повноцінну мову програмування Тьюрінга.

Коментарі

​ У виразах JSONata можуть бути використані коментарі з використанням синтаксису стилю мови «C».

/* Long-winded expressions might need some explanation */
(
  $pi := 3.1415926535897932384626;
  /* JSONata is not known for its graphics support! */
  $plot := function($x) {(
    $floor := $string ~> $substringBefore(?, '.') ~> $number;
    $index := $floor(($x + 1) * 20 + 0.5);
    $join([0..$index].('.')) & 'O' & $join([$index..40].('.'))
  )};
  
  /* Factorial is the product of the integers 1..n */
  $product := function($a, $b) { $a * $b };
  $factorial := function($n) { $n = 0 ? 1 : $reduce([1..$n], $product) };
  
  $sin := function($x){ /* define sine in terms of cosine */
    $cos($x - $pi/2)
  };
  $cos := function($x){ /* Derive cosine by expanding Taylor's series */
    $x > $pi ? $cos($x - 2 * $pi) : $x < -$pi ? $cos($x + 2 * $pi) :
      $sum([0..12].($power(-1, $) * $power($x, 2*$) / $factorial(2*$)))
  };

  [0..24].$sin($*$pi/12).$plot($)
)

рис.11.1. Приклад використання коментарів у виразах JSONata

Подивіться на цей приклад в дії http://try.jsonata.org/ryYn78Q0m

Побудова умов

​ Умовні конструкції «Якщо/тоді/інакше» будуються з використанням умовних операторів "? :"

predicate ? expr1 : expr2

Оцінюється вираз predicate. Якщо вираз повертає true тоді оцінюється вираз expr1 і повертається його значення, інакше обробляється вираз expr2.

Таблиця 11.15.

див. http://try.jsonata.org/

JSONata Result
35.6>20.1 ? 12 : 10 12
35.6<20.1 ? 12 : 10 10

Змінні

​ Будь які назви, що починаються з знаку '$' є змінними. Змінна – це поіменоване посилання на значення. Значення може бути одним із будь-яких типів серед системних типів. Є також вбудовані в JSONata змінні:

  • $ - змінна без імені посилається на значення контексту у будь якій точці вхідної ієрархії JSON.
  • $$ - корінь входу JSON. Тільки потребується у випадках для виходу з теперішнього контексту для тимчасового переходу вниз в інший шлях. Наприклад для перехресного посилання або об’єднання даних.
  • Рідні (вбудовані) функції. Див функції.

Зв’язування змінних

​ Значення можуть бути зв’язані зі змінними наступним чином:

$var_name := "value"

Збережене значення може бути позначено пізніше за допомогою виразу $var_name

Область видимості змінних обмежена ‘блоком’ в якому відбувалось зв’язування. Наприклад:

Invoice.(
  $p := Product.Price;
  $q := Product.Quantity;
  $p * $q
)

Повертає значення Price помножений на Quantity в Product з Invoice.

Функції

Функції є першокласним типом і можуть бути збережені в змінних подібно іншим типам. JSONata забезпечує глобальну бібліотеку вбудованих функцій, що назначені змінним в глобальній області видимості. Наприклад, $uppercase вміщує функцію, яка при виклику зі строковим аргументом str, буде повертати рядок з усіма символам в str, зміненими в верхній регістр.
Функції викликаються з вказівкою аргументів в дужках. Приклади:

  • $uppercase("Hello") повертає рядок "HELLO".
  • $substring("hello world", 0, 5) повертає рядок "hello"
  • $sum([1,2,3]) повертає число 6

Анонімна (лямбда) функція може бути означена, використовуючи наступний синтаксис:

function($l, $w, $h){ $l * $w * $h }

і може бути викликана з допомогою:

function($l, $w, $h){ $l * $w * $h }(10, 10, 5)

що поверне результат 500 Функція може бути назначена змінній для наступного використання (всередині блоку):

$volume := function($l, $w, $h){ $l * $w * $h };
  $volume(10, 10, 5);
)

​ Функції можуть бути означені за допомогою додаткових підписів, яка означують типи параметрів функції. Якщо це передбачено, перш ніж функція буде викликана, будуть перевірятися аргументи. Якщо список аргументів не відповідає підпису, виникне динамічна помилка виникає. ​ Сигнатура функції це рядок в формі <params:return>.params – це послідовність символів типу, кожен з яких представляє тип вхідних аргументів. return – це символ типу, що представляє тип вихідного значення функції. Нижче наведені типи:

Прості типи:

  • b - Boolean
  • n - number
  • s - string
  • l - null

Складені типи:

  • a - array
  • o - object
  • f - function

Типи об’єднання:

  • (sao) - string, array або object
  • (o) – те саме що і o
  • u - еквівалентно (bnsl) тобто Boolean, number, string або null
  • j – будь-який тип JSON. Еквівалентно (bnsloa) тобто Boolean, number, string, null, object або array, але не function
  • x - будь-який тип, Еквівалентно (bnsloaf)

Параметричні типи:

  • a - масив рядків
  • a - масив значень будь-яких типів

Декілька прикладів сигнатур вбудованих функцій JSONata:

  • $count має сигнатуру ``; приймає масив і повертає число.
  • $append має сигнатуру ``; приймає два масиви і повертає масив.
  • $sum має сигнатуру :n>; приймає масив чисел і повертає число.
  • $reduce має сигнатуру :j>; приймає редукуючу функцію f і a (масив об’єктів JSON objects) і повертає об’єкт JSON.

Кожен тип символу може також мати options.

  • + - один або більше аргументів цього типу

    • E.g. $zip has signature ``; it accepts one array, or two arrays, or three arrays, or...
  • ? – опійний аргумент

    • E.g. $join has signature s?:s>; it accepts an array of strings and an optional joiner string which defaults to the empty string. It returns a string.
  • - - якщо аргумент відстуній, використовується значення контексту ("focus").

    • E.g. $length has signature ``; it can be called as $length(OrderID) (one argument) but equivalently as `OrderID.$length()`.

Функції, призначені для змінних, можуть викликати себе, використовуючи це посилання змінної. Це дозволяє визначити рекурсивні функції. Наприклад.

(
  $factorial:= function($x){ $x <= 1 ? 1 : $x * $factorial($x-1) };
  $factorial(4)
)                   

поверне 24

Зауважимо, що фактично можна написати рекурсивну функцію, використовуючи суто анонімні функції (тобто нічого не присвоюється змінним). Це робиться за допомогою комбінатора Y, який може бути цікавим викликом для тих, хто цікавиться функціональним програмуванням. Більше про функції можна прочитати за цим посиланням.

Використання регулярних виразів

​ Про регулярні вирази можна прочитати за цим посиланням.

Робота з датою та часом

Є дві функції, які повертають відмітку часу:

  1. $now() повертає відмітку часу в форматі рядку ISO 8601.
  2. $millis() повертає ту саму відмітку часу як кількість мілісекунд починаючи з опівночі 1-го січня 1970 UTC (the Unix epoch).

Відмітка часу фіксується з початку оцінювання виразу, і та сама відмітка часу повертається для кожного входження $now() або $millis() в тому самому виразі протягом тривалості оцінювання. Наприклад:

Таблиця 11.17.

JSONata { "invoiceTime": $now(), "total": $sum(Account.Order.Product.(Price * Quantity)), "closingTime": $now() }
Result { "invoiceTime": "2018-12-10T13:49:51.141Z", "total": 336.36, "closingTime": "2018-12-10T13:49:51.141Z" }

ISO 8601 формат:

{"myDateTime": "2018-12-10T13:45:00.000Z" }

Таблиця 11.18.

JSONata $toMillis('10/12/2018', '[D]/[M]/[Y]') ~> $fromMillis('[M]/[D]/[Y]')
Result "12/10/2018"

Таблиця 11.19.

JSONata $toMillis('10/12/2018', '[D]/[M]/[Y]') ~> $fromMillis('[FNn], [D1o] [MNn] [YI]')
Result "Monday, 10th December MMXVIII"

Оператори

Navigation Operators

Numeric Operators

Comparison Operators

Boolean Operators

Бібліотека функцій

String functions

Numeric functions

Numeric aggregation functions

Boolean functions

Array Functions

Object functions

Date/Time functions

  1. $now()
  2. $millis()
  3. $fromMillis()
  4. $toMillis()

Higher order functions