首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Javascript搜索筛选到一个数组?

Javascript搜索筛选到一个数组?
EN

Stack Overflow用户
提问于 2021-11-23 16:19:27
回答 3查看 70关注 0票数 0

我正在构建一个nextjs应用程序。一切都很好。但在一个组件中,我面临着一个问题。实际上我不能理解它的功能。我和Sub-Array有个Array。我必须向该Array添加search过滤器。当匹配一个项或子项时,该函数将返回。但是我不明白..。

下面是代码。

这个id数据-

代码语言:javascript
复制
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 " }
]

这里我想添加匹配直接namesub.name的搜索功能。我不明白怎么写函数。如果只有一个Array没有Sub-Array,我可以这样做。

此代码用于first Array而不是Sub-Array

代码语言:javascript
复制
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;

请帮帮我..

EN

回答 3

Stack Overflow用户

发布于 2021-11-23 16:29:39

这是一个递归解决方案-- search()在数据中保留了一个匹配数组,每当它遇到一个名为sub的子数组时,它就会使用这个子数组再次调用自己。

未实现:区分大小写、错误处理或匹配字符串空数组之外的有用输出。

代码语言:javascript
复制
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)

票数 0
EN

Stack Overflow用户

发布于 2021-11-23 17:05:26

当然,您可以进行递归搜索,但您也可以扁平化搜索数据,使其没有深度,然后执行与在代码中所做的完全相同的搜索。为了使数据扁平化,您可以使用数组函数:

代码语言:javascript
复制
data.flatMap(v => v.sub).concat(data.map(({sub, ...item}) => item))

请记住,这不会改变主数据数组。

因此,它首先使用flatMap来获取子属性并将其展平,因此此时您有一个子类别数组,然后它将其与主类别列表连接在一起(仅使用map将它们的子属性删除,从而使其展平)。最后,您有一个包含28个类别(10个主目录+ 18个子目录)的数组来过滤。您可以链接filter方法并继续执行。

票数 0
EN

Stack Overflow用户

发布于 2021-11-23 17:41:03

使用reduce而不是filter。您可以同时对子阵列进行过滤和修改。使用reduce有助于在操作数据的同时过滤数据。

您可以根据需要修改逻辑。

示例代码:

代码语言:javascript
复制
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;
},[])

示例:

代码语言:javascript
复制
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"));

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70084288

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档