我正在 React 中渲染来自 Json 的图像列表,如下所示
{
"images": [
["c8483f65-f67f-48d9-a0f8-78da8f66115d", "Image 0", "https://cdn.shibe.online/shibes/2293625f8b5e74478e51434fbbe158b43f17b04f.jpg", ["servant", "shoes"]],
["4d22a5b7-079d-4f1c-9eba-570165c1f6b1", "Image 1", "https://cdn.shibe.online/shibes/4cc3559217012e477a674862f13d4ac533733cff.jpg", ["screw", "restaurant"]],
["acd3b528-3c56-41c9-a2bc-6094a55e21be", "Image 2", "https://cdn.shibe.online/shibes/6e817b4032beccbd7a3c93dc3b7e1f771e15aaec.jpg", ["cub", "relation"]],
["fca42de6-0eb1-4449-ab91-61b558c7b972", "Image 3", "https://cdn.shibe.online/shibes/d14e008e2aa18bcae592c5e16968050e7ca5ed43.jpg", ["condition", "butter"]],
["73fa77dd-6ec6-4f4d-a991-1bc6b59fb5fa", "Image 4", "https://cdn.shibe.online/shibes/2ca352bdf59566dbffef94724a192713f8970437.jpg", ["zoo", "wheel"]],
["34982d91-d537-4bc0-a481-028879a22c27", "Image 5", "https://cdn.shibe.online/shibes/6e7e3e6a60dcd4b27ac6940a8f44893010f171e4.jpg", ["way", "chess"]],
["4bdc55e4-937a-4208-aff3-981776a2404e", "Image 6", "https://cdn.shibe.online/shibes/20f3c14be166a24376e98b81f9464e153e6ece55.jpg", ["country", "smell"]],
{
我从 JSON 中获取此数据,并将其作为 props 传递给名为 ImageList 的 React 组件,该组件会映射并呈现它们,如下所示
class ImageList extends React.Component{
render(){
console.log(this.props.images)
var mappedImages = this.props.images.map(
(img,index) => {
return (
<Img className = 'img' key = {img[0]} alt = {img[1]} src = {img[2]} tags = {img[3]}/>
);
}
);
return(
<div className = "imageList">
{mappedImages}
</div>
);
}
}
我如何按名称和/或多个标签过滤此图像。 每个数组的第二个元素是图像的名称,最后一个元素是标签数组。
最佳答案
您可以使用Array.prototype.filter()
根据您的搜索检查每个单独的图像和 Array.prototype.find()
或Array.prototype.some()
与 Array.prototype.includes()
检查给定图像的任何标签是否与搜索中的标签匹配:
const images = [
["Image 0", ["servant", "shoes"]],
["Image 1", ["screw", "restaurant"]],
["Image 2", ["cub", "relation"]],
["Image 3", ["condition", "butter"]],
["Image 4", ["zoo", "wheel"]],
["Image 5", ["way", "chess"]],
["Image 6", ["country", "smell"]],
];
const searchName = "Image 3";
const searchTags = ["cub", "country"];
console.log(images.filter(([name, tags]) => {
// With .find:
// return name === searchName || tags.find(tag => searchTags.includes(tag));
// With .some:
return name === searchName || tags.some(tag => searchTags.includes(tag));
}).map(image => image[0]).join(', '));
如果您需要考虑不区分大小写、忽略空格和换行符或仅考虑搜索中的更多字段等问题,您可以向这些图像添加“搜索”属性,您可能只会计算这些图像在服务中,然后使用单个 RegExp
里面Array.prototype.filter()
:
const images = [
["Image 0", ["servant", "shoes"]],
["Image 1", ["screw", "restaurant"]],
["Image 2", ["cub", "relation"]],
["Image 3", ["condition", "butter"]],
["Image 4", ["zoo", "wheel"]],
["Image 5", ["way", "chess"]],
["Image 6", ["country", "smell"]],
];
const searchName = "Image 3";
const searchTags = ["cub", "country"];
// Generate your search RegExp based on the active filters:
const searchRegExp = new RegExp(`${ searchName }|${ searchTags.join('|') }`.replace(/\s/g, '\\s'), 'i');
console.log(searchRegExp);
// You would do this in the service or in a selector, not inside render,
// so that you only compute it once:
const imagesWithSearchTerm = images.map(image => {
const [name, tags] = image;
// Concatenate all fields you want to take into account for the search:
image.push(`${ name }, ${ tags.join(', ') }`);
return image;
});
console.log(imagesWithSearchTerm.filter(image => {
return searchRegExp.test(image[2]);
}).map(image => image[0]).join(', '));
在这个简单的示例中,RegExp
解决方案速度较慢且看起来更复杂,但如果搜索逻辑增长,这实际上可能会更快且更容易理解/推理。
此外,您的过滤逻辑不应位于 render
内部,因为这可能会给您的应用程序带来一些性能问题。您应该将其移至服务/选择器或 use memoization ,无论是在整个组件上还是仅在过滤逻辑周围。
第一个搜索解决方案和以前的内存方法看起来像这样:
const ImageList = React.memo(({
searchName,
searchTags,
images,
}) => {
const mappedImages = images.filter(([name, tags]) => {
return name === searchName || tags.some(tag => searchTags.includes(tag));
}).map(([name, tags, src]) => (
<Img
key={ name }
className="img"
tags={ tags }
src={ src }
/>
));
return (
<div className="imageList">
{ mappedImages }
</div>
);
});
关于javascript - 如何通过多个标签过滤 JSON 中的数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59144468/