Я написал код для страницы, которая принимает пользовательский ввод и выполняет запросы к базе данных, чтобы затем отобразить табличные результаты с помощью d3. Код работает, но довольно повторяющийся и многословный. Я пытаюсь упростить несколько фильтров в одну функцию фильтра на основе объекта, состоящего из пользовательских выборов. Проблема, с которой я сталкиваюсь, состоит в том, что, когда у меня были отдельные функции фильтра для каждого выбора, я мог включать логику для случаев, когда нет выбора пользователя (возвращать весь набор данных). Теперь, когда версия свернута, у меня возникают трудности с реализацией этого фрагмента кода Код довольно длинный, заранее извиняюсь за кирпич.
Сначала я начну с проблемного кода:
var selections = {
dateValue: dateValue,
shapeValArr: shapeValArr,
cityValArr: cityValArr,
stateValArr: stateValArr,
binValArr: binValArr,
commentValue: commentRegex,
countryValue: countryValue
}
console.log(selections)
var filterF = function(selections) {
if (selections.dateValue === "" && selections.shapeValArr === [] && selections.cityValArr === [] && selections.stateValArr === [] && selections.binValArr === [] && selections.countryValue === "All Countries") {
return ufos
} else {
return ufos.filter(ufo => selections.dateValue === ufo.datetime) ||
selections.shapeValArr.reduce((a,b) => a || b === ufo.shape, false) ||
selections.cityValArr.reduce((a,b) => a || b === ufo.city, false) ||
selections.stateValArr.reduce((a,b) => a || b === ufo.state, false) ||
selections.binValArr.reduce((a,b) => a || b === ufo.timeBin, false) ||
selections.commentRegex.test(ufo.comments) === true ||
selections.countryValue === ufo.country
}
}
Вот рабочий код:
var dateFilterF = function(dateValue) {
if (dateValue === "") {
return ufos;
} else {
return ufos.filter(x => x.datetime === dateValue);
}
}
var dateFilter = dateFilterF(dateValue);
var countryValue = document.querySelector('input[name = "countrySelect"]:checked').labels[0].innerText;
var countryFilterF = function(countryValue) {
if (countryValue === "All Countries") {
return ufos;
} else if (countryValue === "United States") {
return ufos.filter(x => x.country === 'us');
} else {
return ufos.filter(x => x.country === 'ca');;
}
}
var countryFilter = countryFilterF(countryValue);
var shapeValue = d3.select("#shapeSelect").selectAll("option").filter(function(){return this.selected});
var shapeValArr = shapeValue._groups[0].map(x => x.value)
var shapeFilterF = function(shapeValArr) {
if (shapeValArr.length === 0) {
return ufos;
} else {
return data.filter(ufo => shapeValArr.reduce((a,b) => a || b === ufo.shape, false));
}
}
var shapeFilter = shapeFilterF(shapeValArr)
var cityValue = d3.select('#citySelect').selectAll("option").filter(function(){return this.selected});
var cityValArr = cityValue._groups[0].map(x => x.value)
var cityFilterF = function(cityValArr) {
if (cityValArr.length === 0) {
return ufos;
} else {
return data.filter(ufo => cityValArr.reduce((a,b) => a || b === ufo.city, false));
}
}
var cityFilter = cityFilterF(cityValArr)
var stateValue = d3.select('#stateSelect').selectAll("option").filter(function(){return this.selected});
var stateValArr = stateValue._groups[0].map(x => x.value)
console.log(`stateValArr: `);
console.log(stateValArr);
var stateFilterF = function(stateValArr) {
if (stateValArr.length === 0) {
return ufos;
} else {
return data.filter(ufo => stateValArr.reduce((a,b) => a || b === ufo.state, false));
}
}
var stateFilter = stateFilterF(stateValArr)
var binValue = d3.select('#binSelect').selectAll("option").filter(function(){return this.selected});
var binValArr = binValue._groups[0].map(x => x.value)
var binFilterF = function(binValArr) {
if (binValArr.length === 0) {
return ufos;
} else {
return data.filter(ufo => binValArr.reduce((a,b) => a || b === ufo.timeBin, false));
}
}
var binFilter = binFilterF(binValArr)
var commentElement = d3.select("#commentSearch");
var commentValue = commentElement.property("value")
var commentFilterF = function(commentValue) {
var regex = new RegExp(commentValue, "gi")
return data.filter(x => regex.test(x.comments) === true);
}
var commentFilter = commentFilterF(commentValue);
var subFilter = dateFilter.filter(ufo => shapeFilter.reduce((a,b) => a || b === ufo, false));
var subFilter2 = subFilter.filter(ufo => stateFilter.reduce((a,b) => a || b === ufo, false));
var subFilter3 = subFilter2.filter(ufo => countryFilter.reduce((a,b) => a || b === ufo, false));
var subFilter4 = subFilter3.filter(ufo => commentFilter.reduce((a,b) => a || b === ufo, false));
var subFilter5 = subFilter4.filter(ufo => cityFilter.reduce((a,b) => a || b === ufo, false));
var subFilter6 = subFilter5.filter(ufo => binFilter.reduce((a,b) => a || b === ufo, false));
var finalFilter = subFilter6;
EDIT:
У меня есть тестовый файл, в котором я тестирую выходные данные ограниченных версий функций. Имея результаты, которые я не могу понять.
var filterF = function(selections) {
return data.filter(ufo => selections.stateValArr.reduce((a,b) => a || b === ufo.state, false) ||
selections.shapeValArr.reduce((a,b) => a || b === ufo.shape, false) ||
selections.dateString === ufo.datetime)
}
var filterF2 = function(selections) {
if (selections.stateValArr === [] || selections.shapeValArr === [] || selections.dateString === "") {
return data;
} else {
return data.filter(ufo => selections.stateValArr.reduce((a,b) => a || b === ufo.state, false) ||
selections.shapeValArr.reduce((a,b) => a || b === ufo.shape, false) ||
selections.dateString === ufo.datetime);
} }
console.log(filterF2(selections).length)
возвращает 111, что является полной длиной набора данных.
var filterF2 = function(selections) {
if (selections.stateValArr === [] || selections.shapeValArr === []) {
return data;
} else {
return data.filter(ufo => selections.stateValArr.reduce((a,b) => a || b === ufo.state, false) ||
selections.shapeValArr.reduce((a,b) => a || b === ufo.shape, false) ||
selections.dateString === ufo.datetime);
}
}
возвращает 0. Единственное отличие состоит в том, что я удалил условие dateString. Но это был || ИЛИ состояние, поэтому я полностью сбит с толку. Тем не менее, я думаю, что это как-то связано с решением общей проблемы.