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

от автора

Задача: Язык 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 экранирование условий — пока ещё не придумал как это элегантно решить.

ссылка на оригинал статьи http://habrahabr.ru/post/163535/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *