[Программирование, Java, Функциональное программирование, Kotlin, Разработка под Linux] Современный JSON процессор
Автор
Сообщение
news_bot ®
Стаж: 6 лет 9 месяцев
Сообщений: 27286
Вместо тысячи слов... Хотели бы вы парсить ndjson'ы в терминале вот таким образом?
where { bool("muted") } max { long("size") } top 3
{"id":4880123,"size":245,"muted":true}
{"id":2392636,"size":107,"muted":true}
{"id":15843320,"size":59,"muted":true}
Если да, то вам под кат.В работе мы нередко используем выгрузки в формате ndjson. Однако их анализ затруднен из-за того что стандартным инструментом для этого является jq с его чудовищным синтаксисом. Так как меня это не устраивало, решил сделать современный json-процессор с удобочитаемым DSL. Что уже умеет этот инструмент?Прежде всего, в наличии есть пять sql-подобных управляющих конструкций для обработки:
where { /* условие фильтрации */ }
order { /* выражение для задания порядка */ }
min { /* выражение для поиска минимальных значений */ }
max { /* выражение для поиска максимальных значений */ }
top ( /* число, лимит для выборки */ )
Все они могут быть использованы как по одиночке, так и скомбинированы друг с другом в любом порядке и с любым количеством повторов. Внутри используется обычный Kotlin, поэтому в выражениях вы также ничем не ограничены. Управляющие конструкции скомбинированные вкупе с выражениями образуют запрос который немедленно вернет вам набор json'ок. Сами запросы также можно комбинировать друг с другом, тогда они будут обработаны за один проход и вы получите несколько выборок в результате.Примеры комбинации выраженийЭтот набор запросов вернет нам 5 разных выборок json. Постарался подчеркнуть читаемость:
max { long("size") } top 3 where { bool("active") },
top(5) where { !bool("active") } min { int("some") },
top(5) min { time("first") to time("last") }, // duration
where { get("arr") int (0) > 5 },
where { !get("broken") } top 3 min { get(4) get("nested") bool("flag") }
Если вы присмотрелись к этому примеру внимательнее, то заметили что в самих выражениях тоже используется лаконичный синтаксис доступа к json полям. Это стало возможно благодаря определенным хелперам выражений, которые являются ничем иным как расширениями для jackson:
// уже знакомые по jackson методы, возвращают ноду:
get(name: String)
get(idx: String)
// о назачении дополнительных расширений комментариев не требуется:
bool(name: String)
bool(idx: String)
int(name: String)
int(idx: String)
double(name: String)
double(idx: String)
string(name: String)
string(idx: String)
time(name: String)
time(idx: String)
Где взять, как начать пользоваться?Из зависимостей вам потребуется лишь Docker и интернет. Прежде всего запустите контейтер с утилитой в вашей директории, например:
docker run -v desired/dir:/opt -it demidko/analyze
Теперь вам доступен шелл контейнера с командой analyze которой можно открывать ndjson файлы:
analyze file.ndjson
Вот и все! Мы попали в шелл для json и можем вводить любые запросы на ваш вкус.Пара слов о внутренней реализацииГлядя на этот синтаксис можно было подумать что внутри творится ад dsl-строения, но на самом деле все гораздо проще. Запросы являются валидным подмножеством Kotlin и используют определенные прямо в исходном коде Kotlin функции. Запускается эта радость через известный jsr223 на котором подробно останавливаться нет смысла.
А вот про реализацию самих запросов стоит рассказать, остановлюсь на примере из кода:
typealias Query = (MutableList<JsonNode>, JsonNode) -> Unit
class Action(val action: MutableList<JsonNode>.(JsonNode) -> Unit) :
Query by { list, el ->
list.action(el)
}
infix fun Action.top(limit: Int) = Action {
action(it)
while (size > limit) {
removeLast()
}
}
fun order(comparator: Comparator<JsonNode>) = Action {
add(it)
sortWith(comparator)
}
infix fun Action.where(filter: JsonNode.() -> Boolean) = Action {
if (it.filter()) {
action(it)
}
}
Возможно вы удивитесь, но эти несколько функций и образуют ядро синтаксиса благодаря инфиксной нотации, а все остальное по сути синтаксические дополнения. Исходный код лежит на GitHub: https://github.com/demidko/analyzeВсем удачного дня! Буду рад услышать критику и предложения.
===========
Источник:
habr.com
===========
Похожие новости:
- [Высокая производительность, Разработка веб-сайтов, JavaScript, Программирование, Клиентская оптимизация] Оптимизации в вебе — дорого, сложно, и уже не нужно?
- [Программирование микроконтроллеров] Программирование ESP32 с использованием JTAG программатора ESP-Prog и ESP-IDF
- [PHP, Программирование, Java] Java в сравнении с PHP: Что выбрать в 2021 году
- [JavaScript, Программирование, Конференции, Видеоконференцсвязь] Видеочат с возможностью совместного редактирования текста при помощи Twilio Sync (перевод)
- [Программирование, Софт] 6 вещей, которые бизнес-лидеры должны знать о RPA в 2021 году (перевод)
- [JavaScript, Разработка мобильных приложений, Разработка под Tizen, Производство и разработка электроники, Мониторы и ТВ] Разработка Tizen-приложений для Samsung Smart TV: полный гайд для Javascript-разработчиков
- [Разработка мобильных приложений, Разработка под Android, Kotlin] View Model не обязательно наследоваться от ViewModel
- [Groovy & Grails, Разработка под Android, Kotlin, Gradle] Gradle Plugin: Что, зачем и как?
- [Ненормальное программирование, Программирование, Совершенный код, C++, C] Металингвистический совратитель Си. Опус III: Садистская машина
- [Java] Реактивное программирование со Spring (перевод)
Теги для поиска: #_programmirovanie (Программирование), #_java, #_funktsionalnoe_programmirovanie (Функциональное программирование), #_kotlin, #_razrabotka_pod_linux (Разработка под Linux), #_kotlin, #_jq, #_analyze, #_json, #_ndjson, #_docker, #_programmirovanie (
Программирование
), #_java, #_funktsionalnoe_programmirovanie (
Функциональное программирование
), #_kotlin, #_razrabotka_pod_linux (
Разработка под Linux
)
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Текущее время: 22-Ноя 03:04
Часовой пояс: UTC + 5
Автор | Сообщение |
---|---|
news_bot ®
Стаж: 6 лет 9 месяцев |
|
Вместо тысячи слов... Хотели бы вы парсить ndjson'ы в терминале вот таким образом? where { bool("muted") } max { long("size") } top 3
{"id":4880123,"size":245,"muted":true} {"id":2392636,"size":107,"muted":true} {"id":15843320,"size":59,"muted":true} where { /* условие фильтрации */ }
order { /* выражение для задания порядка */ } min { /* выражение для поиска минимальных значений */ } max { /* выражение для поиска максимальных значений */ } top ( /* число, лимит для выборки */ ) max { long("size") } top 3 where { bool("active") },
top(5) where { !bool("active") } min { int("some") }, top(5) min { time("first") to time("last") }, // duration where { get("arr") int (0) > 5 }, where { !get("broken") } top 3 min { get(4) get("nested") bool("flag") } // уже знакомые по jackson методы, возвращают ноду:
get(name: String) get(idx: String) // о назачении дополнительных расширений комментариев не требуется: bool(name: String) bool(idx: String) int(name: String) int(idx: String) double(name: String) double(idx: String) string(name: String) string(idx: String) time(name: String) time(idx: String) docker run -v desired/dir:/opt -it demidko/analyze
analyze file.ndjson
А вот про реализацию самих запросов стоит рассказать, остановлюсь на примере из кода: typealias Query = (MutableList<JsonNode>, JsonNode) -> Unit
class Action(val action: MutableList<JsonNode>.(JsonNode) -> Unit) : Query by { list, el -> list.action(el) } infix fun Action.top(limit: Int) = Action { action(it) while (size > limit) { removeLast() } } fun order(comparator: Comparator<JsonNode>) = Action { add(it) sortWith(comparator) } infix fun Action.where(filter: JsonNode.() -> Boolean) = Action { if (it.filter()) { action(it) } } =========== Источник: habr.com =========== Похожие новости:
Программирование ), #_java, #_funktsionalnoe_programmirovanie ( Функциональное программирование ), #_kotlin, #_razrabotka_pod_linux ( Разработка под Linux ) |
|
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Текущее время: 22-Ноя 03:04
Часовой пояс: UTC + 5