按多个属性筛选JSON数据



我有类似于data.JSON的JSON数据。我的目标是让用户按类别1-4过滤组合的数据(如按类别1和3过滤(。为此,我从api.js中获取了用户使用getSelectedFilterOption选择的选项。然后,我编写了一个函数,其中包含了api.jsfilterRowsByOption中所有16种过滤可能性。这是我让它工作的天真方法(确实如此(,但我认为这不是一种实用的方法。特别是,它是不可扩展的,比如如果我想在未来按5个类别组合进行筛选,我必须写出所有32种可能性。

有没有更方便的方法来实现我想要的?

提前谢谢。

data.json

{
(...),
"category1": "a",
"category2": "b",
"category3": "c",
"category4": "d",
(...)
}

index.php

<select id="filterCategory1" class="form-select">
<option selected>All</option>
<?php filter_cat1(); ?>
</select>
<select id="filterCategory2" class="form-select">
<option selected>All</option>
<?php filter_cat2(); ?>
</select>
<select id="filterCategory3" class="form-select">
<option selected>All</option>
<?php filter_cat3(); ?>
</select>
<select id="filterCategory1" class="form-select">
<option selected>All</option>
<?php filter_cat4(); ?>
</select>

api.js

function getSelectedFilterOption(data) {
let selectedFilterOptions = ["All", "All", "All", "All"]; // initial state
let selectedFilterOption = [];
const selectFilter = document.querySelectorAll("#filterCategory1, #filterCategory2, #filterCategory3, #filterCategory4");
for (let i = 0; i < selectFilter.length; i++) {
selectFilter[i].addEventListener("change", function(e) {

selectedFilterOption[i] = selectFilter[i].options[selectFilter[i].selectedIndex].text;

selectedFilterOptions[i] = selectedFilterOption[i];
console.log(selectedFilterOptions);
filterRowsByOption(data, selectedFilterOptions);
});
}
}
function filterRowsByOption(data, selectedFilterOptions) {
const container = document.querySelector(".container");
container.innerHTML = "";
let filteredData = data;
// no filter
if (selectedFilterOptions[0] === "All" && selectedFilterOptions[1] === "All" && selectedFilterOptions[2] === "All" && selectedFilterOptions[3] === "All") {
displayAllRows(data);
}
// category1 chosen, category2 chosen, category3 chosen, category4 chosen
else if (selectedFilterOptions[0] !== "All" && selectedFilterOptions[1] !== "All" && selectedFilterOptions[2] !== "All" && selectedFilterOptions[3] !== "All") {
filteredData = data.filter(row => row.category1 === selectedFilterOptions[0] && row.category2 === selectedFilterOptions[1] && row.category3 === selectedFilterOptions[2] && row.category4 === selectedFilterOptions[3]);
}
// category1 chosen, category2 chosen, category3 chosen
else if...
(...)
}

当然,你不应该重复自己两次以上。不过,为了演示,我重复了html。

关于此解决方案:通过比较不为空的类别来filter数组。

var data = [{
"category1": "1",
"category2": "2",
"category3": "2",
"category4": "1",
},
{
"category1": "1",
"category2": "2",
"category3": "3",
"category4": "4",
}
];
var selects = document.querySelectorAll("[data-category]");
selects.forEach(function(select) {
select.addEventListener("change", apply_filters);
})
function apply_filters() {
var result = data.filter(function(obj) {
var ok = true;
selects.forEach(function(select) {
var category = select.getAttribute("data-category");
ok = ok && (select.value ? obj[category] == select.value : true)
})
return ok;
})
console.log(result);
}
<select id="filterCategory1" data-category="category1" class="form-select">
<option value="" selected>All Category1</option>
<option value="1">1</option>
<option value="2">2</option>
</select>
<select id="filterCategory2" data-category="category2" class="form-select">
<option value="" selected>All Category2</option>
<option value="1">1</option>
<option value="2">2</option>
</select>
<select id="filterCategory3" data-category="category3" class="form-select">
<option value="" selected>All Category3</option>
<option value="1">1</option>
<option value="2">2</option>
</select>
<select id="filterCategory1" data-category="category4" class="form-select">
<option value="" selected>All Category4</option>
<option value="1">1</option>
<option value="2">2</option>
</select>

最新更新