我正在构建一个nextjs应用程序。一切都很好。但在一个组件中,我面临着一个问题。实际上我不能理解它的功能。我和Sub-Array有个Array。我必须向该Array添加search过滤器。当匹配一个项或子项时,该函数将返回。但是我不明白..。
下面是代码。
这个id数据-
export default [
{
name: "Top Wear",
sub: [
{ name: "T-Shirts" },
{ name: "Casual Shirts" }
]
}
{
name: "Western Wear",
sub: [
{ name: "Dresses" },
{ name: "Jumpsuits" }
]
},
{ name: "Plus Size" },
{ name: "Sunglasses and Frames" },
{
name: "Footwear",
sub: [
{ name: "Casual Shoes" },
{ name: "Sports Shoes" }
]
},
{
name: "Lingerie & Sleepwear",
sub: [
{ name: "Bra" },
{ name: "Briefs" }
]
},
{
name: "Sports & Active Wear",
sub: [
{ name: "Sports Shoes" },
{ name: "Sports Sandals" },
{ name: "Active T-Shirts" },
{ name: "Active T-Shirts" },
]
},
{
name: "Gadgets",
sub: [
{ name: "Smart Wearables" },
{ name: "Fitness Gadgets" }
]
},
{ name: "Bag & Backpacks" },
{ name: "Luggages & Trolleys " }
]这里我想添加匹配直接name或sub.name的搜索功能。我不明白怎么写函数。如果只有一个Array没有Sub-Array,我可以这样做。
此代码用于first Array而不是Sub-Array
import { useState, useEffect } from "react";
//Data
import CategoriesData from "Data/Header/SearchBar.data";
const Categories = ({ setFilterData, filterData }) => {
const [categories, setCategories] = useState(CategoriesData);
const [input, setInput] = useState("");
useEffect(() => {
if (input.length > 0) {
const mathches = CategoriesData.filter(item => {
const escapeRegExp = (str) => str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&")
const regex = new RegExp(escapeRegExp(input), "gi");
return item.name.match(regex);
})
setCategories(mathches);
} else {
setCategories(CategoriesData);
}
}, [CategoriesData, input]);
return (
<Box>
<Box>
<InputBase
value={input}
onChange={(e) => setInput(e.target.value)}
/>
</Box>
<List>
{categories &&
categories.map((category, i) => (
<Box key={i}>
<ListItem>
<ButtonBase>
<Typography>
{category.name}
</Typography>
</ButtonBase>
</ListItem>
{category.sub &&
category.sub.map((subCategory, i) => (
<ListItem key={i}>
<ButtonBase>
<Typography>
{subCategory.name}
</Typography>
</ButtonBase>
</ListItem>
))
}
</Box>
))
}
</List>
</Box>
);
};
export default Categories;请帮帮我..
发布于 2021-11-23 16:29:39
这是一个递归解决方案-- search()在数据中保留了一个匹配数组,每当它遇到一个名为sub的子数组时,它就会使用这个子数组再次调用自己。
未实现:区分大小写、错误处理或匹配字符串空数组之外的有用输出。
const search = (str, data) => {
let out = [];
for (let obj of data) {
if (obj.name.indexOf(str) > -1) {
out.push(obj.name)
}
if (obj.sub) {
// recurse if there's a child array
out.push(search(str, obj.sub))
}
}
return out.flat()
}
output = search("e", [{
name: "Top Wear",
sub: [{
name: "T-Shirts"
},
{
name: "Casual Shirts"
}
]
}, {
name: "Western Wear",
sub: [{
name: "Dresses"
},
{
name: "Jumpsuits"
}
]
},
{
name: "Plus Size"
},
{
name: "Sunglasses and Frames"
},
{
name: "Footwear",
sub: [{
name: "Casual Shoes"
},
{
name: "Sports Shoes"
}
]
},
{
name: "Lingerie & Sleepwear",
sub: [{
name: "Bra"
},
{
name: "Briefs"
}
]
},
{
name: "Sports & Active Wear",
sub: [{
name: "Sports Shoes"
},
{
name: "Sports Sandals"
},
{
name: "Active T-Shirts"
},
{
name: "Active T-Shirts"
},
]
},
{
name: "Gadgets",
sub: [{
name: "Smart Wearables"
},
{
name: "Fitness Gadgets"
}
]
},
{
name: "Bag & Backpacks"
},
{
name: "Luggages & Trolleys "
}
])
console.log(output)
发布于 2021-11-23 17:05:26
当然,您可以进行递归搜索,但您也可以扁平化搜索数据,使其没有深度,然后执行与在代码中所做的完全相同的搜索。为了使数据扁平化,您可以使用数组函数:
data.flatMap(v => v.sub).concat(data.map(({sub, ...item}) => item))请记住,这不会改变主数据数组。
因此,它首先使用flatMap来获取子属性并将其展平,因此此时您有一个子类别数组,然后它将其与主类别列表连接在一起(仅使用map将它们的子属性删除,从而使其展平)。最后,您有一个包含28个类别(10个主目录+ 18个子目录)的数组来过滤。您可以链接filter方法并继续执行。
发布于 2021-11-23 17:41:03
使用reduce而不是filter。您可以同时对子阵列进行过滤和修改。使用reduce有助于在操作数据的同时过滤数据。
您可以根据需要修改逻辑。
示例代码:
const mathches = CategoriesData.reduce((acc, item) => {
const escapeRegExp = (str) => str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&")
const regex = new RegExp(escapeRegExp(input), "gi");
if(item.sub) {
const sub = item.sub.filter(({name}) => name.match(regex))
if(sub.length){
acc.push({name: item.name, sub})
}
}
else if(item.name.match(regex)){
acc.push(item)
}
return acc;
},[])示例:
const data = [
{
name: "Top Wear",
sub: [{ name: "T-Shirts" }, { name: "Casual Shirts" }],
},
{
name: "Western Wear",
sub: [{ name: "Dresses" }, { name: "Jumpsuits" }],
},
{ name: "Plus Size" },
{ name: "Sunglasses and Frames" },
{
name: "Footwear",
sub: [{ name: "Casual Shoes" }, { name: "Sports Shoes" }],
},
{
name: "Lingerie & Sleepwear",
sub: [{ name: "Bra" }, { name: "Briefs" }],
},
{
name: "Sports & Active Wear",
sub: [
{ name: "Sports Shoes" },
{ name: "Sports Sandals" },
{ name: "Active T-Shirts" },
{ name: "Active T-Shirts" },
],
},
{
name: "Gadgets",
sub: [{ name: "Smart Wearables" }, { name: "Fitness Gadgets" }],
},
{ name: "Bag & Backpacks" },
{ name: "Luggages & Trolleys " },
];
const search = (data, input) => {
const mathches = data.reduce((acc, item) => {
const escapeRegExp = (str) =>
str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&");
const regex = new RegExp(escapeRegExp(input), "gi");
if (item.sub) {
const sub = item.sub.filter(({ name }) => name.match(regex));
if (sub.length) {
acc.push({ name: item.name, sub });
}
} else if (item.name.match(regex)) {
acc.push(item);
}
return acc;
}, []);
return mathches;
};
console.log(search(data, "Top Wear"));
console.log(search(data, "Sandals"));
console.log(search(data, "Shoes"));
https://stackoverflow.com/questions/70084288
复制相似问题