- PVSM.RU - https://www.pvsm.ru -

Jsqry — библиотека для запросов к JS объектам и массивам

Представляю вашему вниманию небольшую js-библиотеку Jsqry [1].
Проще всего проиллюстрировать её назначение следующим примером.

До:

var name;
for (var i = 0; i < users.length; i++) {
    if (users[i].id == 123) {
        name = users[i].name;
        break;
    }
}

После:

var name = one(users, '[_.id==?].name', 123);

Библиотечка позволяет извлекать информацию из объектов/массивов в одну строку, используя несложный язык запросов, вместо написания циклов (подчас вложенных).

По сути, она реализует всего две функции:

  • query — для возвращения списка результатов и
  • one — для возвращения первого найденного результата.

Список возможностей включает:

  1. Фильтрацию
  2. Трансформацию
  3. Индексы/срезы в стиле Python

Библиотека появилась спонтанно в одном проекте, построенном на модном ныне подходе одностраничного приложения [2]. Мы загружаем один большой JSON, части которого затем используются для рендеринга на клиенте разных представлений сайта. И вот для выдирания этих самых частей и захотелось более удобного способа. Затем, впрочем, библиотека оказалась востребована и в других случаях.

Поясню немного по функционалу. Запрос в общем случае может иметь вид

field1.field2[ condition or index or slice ].field3{ transformation }.field4

Тут:

  • field1.field2.field3... — обычный доступ к полям объектов, как в js
  • [ condition ] — фильтрация
  • [ index ] — доступ по индексу, тоже как в js
  • [ from:to:step ]срезы в стиле Python [3]
  • { transformation } — преобразование объектов

На condition и transformation стоит остановиться подробнее.
На самом деле тут все очень просто. Достаточно понять, что каждое выражение внутри квадратных/фигурных скобок при выполнении заменяется на функцию по такому принципу:

condition_or_transformation ⟶ function(_,i) { return condition_or_transformation }

(тут _ — значение передаваемого элемента, i — его индекс).

Пример:

query([1,2,3,4,5],'[_>2]{_+10}') // [13, 14, 15]

Также поддерживаются параметризация запроса:

query([1,2,3,4,5],'[_>?]{_+?}', 2, 10) // [13, 14, 15] 

Комбинируя эти возможности можно строить весьма сложные и гибкие запросы. Больше примеров использования можно посмотреть тут [4].

Из интересного в реализации — AST [5] дерево запроса кешируется, что придает библиотеке скорости.

Разумеется, моя библиотека не уникальна в своём роде. Стоит привести "небольшой" список аналогов:

Зачем еще одна библиотека? На самом деле, она поддерживает не весь возможный спектр типов запросов, а только то что было нужно в нашем проекте в большинстве случаев. За счет этого простота и скорость. Также, чрезвычайно простой API, вдохновленный подходом JQuery.

Буду рад выслушать критику и предложения по улучшению.

Автор: xonix

Источник [11]


Сайт-источник PVSM.RU: https://www.pvsm.ru

Путь до страницы источника: https://www.pvsm.ru/javascript/138986

Ссылки в тексте:

[1] Jsqry: https://github.com/xonixx/jsqry

[2] одностраничного приложения: https://en.wikipedia.org/wiki/Single-page_application

[3] срезы в стиле Python: https://habrahabr.ru/post/89456/

[4] можно посмотреть тут: https://github.com/xonixx/jsqry/blob/master/spec/spec.js

[5] AST: https://en.wikipedia.org/wiki/Abstract_syntax_tree

[6] http://danski.github.io/spahql/: http://danski.github.io/spahql/

[7] http://objectpath.org/: http://objectpath.org/

[8] https://github.com/crcn/sift.js: https://github.com/crcn/sift.js

[9] http://defiantjs.com/: http://defiantjs.com/

[10] и так далее...: http://orangevolt.blogspot.com/2012/12/8-ways-to-query-json-structures.html

[11] Источник: https://habrahabr.ru/post/303624/?utm_source=habrahabr&utm_medium=rss&utm_campaign=best