Pull to refresh

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

Reading time2 min
Views11K

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


До:


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

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


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


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

Тут:


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

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


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


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



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


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

Tags:
Hubs:
+15
Comments58

Articles

Change theme settings