jsFind. Выборка данных из массива объектов

в 7:13, , рубрики: javascript, JS, json, ненормальное программирование, метки:

Задача: Язык javascript. Имеется большой массив объектов. Нужно выбрать из массива некоторые объекты, в зависимости от значений свойств этих объектов.

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

В качестве вступления: основной код был написан больше двух лет назад. Сначала он использовался как временный и в последствии я его хотел заменить обработкой на backend'e. Время шло код обрастал, мутировал и начал «инфицировать» собой другие проекты. И на моё удивление он везде очень хорошо приживался, заменяя собой связку клиент-сервер в тех случаях где было не так много данных, например, каталоги товаров в которых кол-во наименований не более 1000шт.

Для демонстрации подготовил вот такой простой массивчик(автолюбителям посвещается):

var cars=[
			{
				brand: 'audi',		//фирма производитель
				model: 'a4',		//модель
				volume_engine: '1.8',	//объём двигателя
				hp: '120',		//кол-во лошадиных сил
				awd: 'нет',   		//полный привод [да/нет]
				automat: 'да',		//автомат [да/нет]
			},
			{
				brand: 'audi',		//фирма производитель
				model: 'a4 allroad',	//модель
				volume_engine: '2',	//объём двигателя
				hp: '211',		//кол-во лошадиных сил
				awd: 'да',   		//полный привод [да/нет]
				automat: 'да',		//автомат [да/нет]
			},
			{
				brand: 'audi',		//фирма производитель
				model: 'a6',		//модель
				volume_engine: '2',	//объём двигателя
				hp: '180',		//кол-во лошадиных сил
				awd: 'нет',   		//полный привод [да/нет]
				automat: 'да',		//автомат [да/нет]
			},
			{
				brand: 'bmw',		//фирма производитель
				model: '3 Series',	//модель
				volume_engine: '1.6',	//объём двигателя
				hp: '135',		//кол-во лошадиных сил
				awd: 'нет',   		//полный привод [да/нет]
				automat: 'нет',		//автомат [да/нет]
			},
			{
				brand: 'bmw',		//фирма производитель
				model: '5 Series',	//модель
				volume_engine: '3',	//объём двигателя
				hp: '258',		//кол-во лошадиных сил
				awd: 'нет',   		//полный привод [да/нет]
				automat: 'да',		//автомат [да/нет]
			},
			{
				brand: 'volkswagen',	//фирма производитель
				model: 'passat',	//модель
				volume_engine: '1.8',	//объём двигателя
				hp: '152',		//кол-во лошадиных сил
				awd: 'нет',   		//полный привод [да/нет]
				automat: 'да',		//автомат [да/нет]
			},
]

Начнём сразу с примеров. Не обращайте внимание на «ещё...» — осталось от console.log(). Для начала выберем из массива все автомобили марки audi (попробовать):

cars.find({ brand:"audi"})

//результат:
[
	{ brand="audi",  model="a4",  volume_engine="1.8",  ещё...}, 
	{ brand="audi",  model="a4 allroad",  volume_engine="2",  ещё...},
	{ brand="audi",  model="a6",  volume_engine="2",  ещё...}
]

Выберем все модели a4 марки audi (попробовать):

cars.find({ brand: "audi", model: "%a4%" })

//результат:
[
	{ brand="audi",  model="a4",  volume_engine="1.8",  ещё...},
	{ brand="audi",  model="a4 allroad",  volume_engine="2",  ещё...}
]

Выберем все модели a4 марки audi с полным приводом (попробовать):

cars.find({ brand: "audi", model: "%a4%", awd:"да" })

//результат:
[
	{ brand="audi",  model="a4 allroad",  volume_engine="2",  ещё...}
]

— тоже самое, но выборка идёт по очереди (попробовать):

cars.find({ brand: "audi" }).find({ model: "%a4%" }).find({ awd: "да" })

//результат:
[
	{ brand="audi",  model="a4 allroad",  volume_engine="2",  ещё...}
]

А теперь найдем все авто с мощностью двигателя больше 200 лошадок (попробовать):

cars.find({ hp: ">=200" })

//результат:
[
	{ brand="audi",  model="a4 allroad",  volume_engine="2",  ещё...}, 
	{ brand="bmw",  model="5 Series", volume_engine="3",  ещё...}
]

Выберем двух и трёхлитровые машины (попробовать):

cars.find({ volume_engine: ["2","3"] })

//результат:
[
	{ brand="audi",  model="a4 allroad",  volume_engine="2",  ещё...}, 
	{ brand="audi",  model="a6",  volume_engine="2",  ещё...}, 
	{ brand="bmw",  model="5 Series",  volume_engine="3",  ещё...}
]

Выберем двух и трёхлитровые машины фирмы audi (попробовать):

cars.find({ brand:"audi", volume_engine:["2","3"] })

//результат:
[
	{ brand="audi",  model="a4 allroad",  volume_engine="2",  ещё...}, 
	{ brand="audi",  model="a6",  volume_engine="2",  ещё...}
]

Выберем все машины у которых объём двигателя строго меньше 2ух литров и больше или равен 3ём (попробовать):

cars.find({volume_engine:["<2",">=3"] })

//результат:
[
	{ brand="audi",  model="a4",  volume_engine="1.8",  ещё...}, 
	{ brand="bmw",  model="3 Series",  volume_engine="1.6",  ещё...}, 
	{ brand="bmw",  model="5 Series",  volume_engine="3",  ещё...},
	{ brand="volkswagen",  model="passat",  volume_engine="1.8",  ещё...}
]

Думаю суть понятна. Метод find из исходного массива выбирает объекты, удовлетворяющие условиям, которые передаются методу, в качестве параметров. На выходе получается обычный массив объектов, и из него снова можно выбирать данные: cars.find({...}).find({...}).find({...}).find({...});

GitHub
jsfiddle

p.s.#0 о методе find в MongoDB знаю, с него то всё и началось. Постараюсь в будущем сделать очень-очень похожим на него.
p.s.#1 в сл.версии добавлю возможность расширять метод find своими способами фильтрации.
p.s.#2 в следующей статье расскажу о jquery плагине на основе find.js, который берёт массив объектов и формирует из него фильтр со списком товаров и пагинацией, и разметкой bootstrap.
p.s.#3 экранирование условий — пока ещё не придумал как это элегантно решить.

Автор: babarun

Источник

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js