简体   繁体   English

Javascript 搜索过滤器到数组?

[英]Javascript search filter to a array?

I am building a nextjs application.我正在构建一个nextjs应用程序。 Everything is okay.一切正常。 But in one component I am facing a problem.但在一个组件中,我面临一个问题。 Actually I can't understand the functionality.其实我无法理解它的功能。 I have an Array with Sub-Array .我有一个带有Sub-Array Array I have to add search filter to that Array .我必须将search过滤器添加到该Array And the function will return when match an item or sub item.并且 function 将在匹配项目或子项目时返回。 But I can't understand..但是看不懂。。

Here is the code.这是代码。

This id data-这个 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 " }
]

Here I want to add search function that match direct name or sub.name .在这里,我想添加匹配直接namesub.name I can't understand How can I write function.我不明白我该怎么写 function。 I can do that if there are just one Array no Sub-Array ..如果只有一个Array no Sub-Array ,我可以做到这一点。

This code is for first Array not Sub-Array此代码适用于第一个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;

Please help me..请帮我..

Here's a recursive solution -- search() keeps an array of matches within the data, and whenever it encounters a child array named sub it calls itself again with just that subarray.这是一个递归解决方案—— search()在数据中保留一个匹配数组,并且每当它遇到一个名为sub的子数组时,它会再次使用该子数组调用自身。

Not implemented: case-sensitivity, error handling, or useful output beyond a bare array of matched strings.未实现:区分大小写、错误处理或有用的 output 超出匹配字符串的裸数组。

 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)

Of course you can do recursive search, but you can also flatten the search data so it has no depth and then do the exact same search you are doing in your code.当然,您可以进行递归搜索,但您也可以将搜索数据展平,使其没有深度,然后执行与您在代码中所做的完全相同的搜索。 In order to flatten your data you can use array functions:为了展平您的数据,您可以使用数组函数:

data.flatMap(v => v.sub).concat(data.map(({sub, ...item}) => item))

Keep in mind this does not alter the main data array.请记住,这不会改变主数据数组。

So first of all it uses flatMap to get the sub properties and flattens them, so at this point you have an array of sub categories, then it concatenates it with the list of main categories (only using map their sub property is now removed cause its flattened).所以首先它使用flatMap来获取属性并将它们展平,所以此时你有一个子类别数组,然后它将它与主要类别列表连接起来(仅使用 map 他们的子属性现在被删除了,因为它的压扁)。 In the end you have an array of 28 categories (10 main + 18 sub) to filter.最后,您有一个包含 28 个类别(10 个主要 + 18 个子)的数组来过滤。 You can chain the filter method and keep going.您可以链接filter方法并继续。

Instead of filter use reduce.代替过滤器使用减少。 You can filter and modify the sub-array same time.您可以同时过滤和修改子数组。 Using reduce help to manipulate data and filter same time.使用 reduce 帮助同时操作数据和过滤。

You can modify logic as your need.您可以根据需要修改逻辑。

Sample Code:示例代码:

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;
},[])

Example:例子:

 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"));

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM