递归过滤搜索栏的 json 数据
recursively filter json data for search bar
我正在尝试编写搜索栏过滤器以响应 table。
困难的部分是JSON数据结构,它可能具有未知深度的父子关系,例如:
data = [
{
input: "row 0 ",
output: "output of the first row"
subRows: [],
},
{
input: "row 1",
output: "output of the second row"
subRows: [
{
input: "third row 1.0",
output: "output of the 3° row"
subRows: [
{
input: "row 1.0.0",
output: "output of the third row"
subRows: [],
},
],
},
{
input: "row 1.1",
output: "output of 2 rows after the third (fifth)"
subRows: []
},
],
},
];
附加信息:上面的每个对象 JSON 在我的 html(jsx) table 中表示为一行,他的子行是其他行,可以通过用户点击。
我以为我可以用 ES6 的过滤函数来处理它,但我不知道怎么做。
这是我期望的结果,如果用户在搜索栏中输入例如:“third”
{
input: "third row 1.0",
output: "output of the 3° row"
subRows: []
},
{
input: "row 1.1",
output: "output of 2 rows after the third (fifth)",
subRows: []
},
这是我的代码:
const updateFilter = (filterValue) => {
let results = data.filter(function f(row) {
if (Object.values(row).includes(filterValue.toLowerCase())) {
return true;
}
if (row.subRows && row.subRows.length > 0) {
return (row.subRows = row.subRows.filter(f));
}
});
console.log(JSON.stringify(results));
};
}
这里是codePen中的代码:https://codepen.io/ardiz90/pen/yLajjRQ?editors=0012
感谢您的帮助!
编辑:原来我无法展平行,因为 table 需要树结构中的数据才能呈现它,所以下面写的展平行的解决方案不是可行..
您可以先展平嵌套对象,然后相应地过滤值。我还认为您使用 Object.values(...).includes(...)
的过滤机制无法正常工作。
这是一个展平对象并过滤它们的示例:
// returns a Array containing the element itself and its children recursively
function flattenWithSubRows(entries) {
return entries.flatMap(entry => [
entry, ...flattenWithSubRows(entry.subRows)
]);
}
// gets an array containing only the objects
// containing the searchString in a string property
function getAllMatchingItems(searchString, array) {
const isMatching = entry => Object.values(entry)
.filter(val => typeof val === 'string')
.map(val => val.toLowerCase())
.some(val => val.includes(searchString.toLowerCase()));
return flattenWithSubRows(array).filter(isMatching)
}
const filtered = getAllMatchingItems("third", data);
console.log(filtered);
我正在尝试编写搜索栏过滤器以响应 table。
困难的部分是JSON数据结构,它可能具有未知深度的父子关系,例如:
data = [
{
input: "row 0 ",
output: "output of the first row"
subRows: [],
},
{
input: "row 1",
output: "output of the second row"
subRows: [
{
input: "third row 1.0",
output: "output of the 3° row"
subRows: [
{
input: "row 1.0.0",
output: "output of the third row"
subRows: [],
},
],
},
{
input: "row 1.1",
output: "output of 2 rows after the third (fifth)"
subRows: []
},
],
},
];
附加信息:上面的每个对象 JSON 在我的 html(jsx) table 中表示为一行,他的子行是其他行,可以通过用户点击。
我以为我可以用 ES6 的过滤函数来处理它,但我不知道怎么做。
这是我期望的结果,如果用户在搜索栏中输入例如:“third”
{
input: "third row 1.0",
output: "output of the 3° row"
subRows: []
},
{
input: "row 1.1",
output: "output of 2 rows after the third (fifth)",
subRows: []
},
这是我的代码:
const updateFilter = (filterValue) => {
let results = data.filter(function f(row) {
if (Object.values(row).includes(filterValue.toLowerCase())) {
return true;
}
if (row.subRows && row.subRows.length > 0) {
return (row.subRows = row.subRows.filter(f));
}
});
console.log(JSON.stringify(results));
};
}
这里是codePen中的代码:https://codepen.io/ardiz90/pen/yLajjRQ?editors=0012
感谢您的帮助!
编辑:原来我无法展平行,因为 table 需要树结构中的数据才能呈现它,所以下面写的展平行的解决方案不是可行..
您可以先展平嵌套对象,然后相应地过滤值。我还认为您使用 Object.values(...).includes(...)
的过滤机制无法正常工作。
这是一个展平对象并过滤它们的示例:
// returns a Array containing the element itself and its children recursively
function flattenWithSubRows(entries) {
return entries.flatMap(entry => [
entry, ...flattenWithSubRows(entry.subRows)
]);
}
// gets an array containing only the objects
// containing the searchString in a string property
function getAllMatchingItems(searchString, array) {
const isMatching = entry => Object.values(entry)
.filter(val => typeof val === 'string')
.map(val => val.toLowerCase())
.some(val => val.includes(searchString.toLowerCase()));
return flattenWithSubRows(array).filter(isMatching)
}
const filtered = getAllMatchingItems("third", data);
console.log(filtered);