假设我有一个对象myBook
和一个数组allCategories
。
const allCategories = ["sciencefiction", "manga", "school", "art"];
const myBook = {
isItScienceFiction: true,
isItManga: false,
isItForKids: false
}
我想要的内容:循环遍历类别以检查Book的值,例如,检查"sciencefiction"
是否存在于Book对象中,然后检查其值
我尝试过的方法:
1)使用indexOf
allCategories.map((category) => {
Object.keys(myBook).indexOf(category)
// Always returns -1 because "sciencefiction" doesn't match with "isItScienceFiction"
});
2)使用includes
allCategories.map((category) => {
Object.keys(myBook).includes(category)
// Always returns false because "sciencefiction" doesn't match with "isItScienceFiction"
});
预期输出:
allCategories.map((category) => {
// Example 1 : Returns "sciencefiction" because "isItScienceFiction: true"
// Example 2 : Returns nothing because "isItManga: false"
// Example 3 : Returns nothing because there is not property in myBook with the word "school"
// Example 4 : Returns nothing because there is not property in myBook with the word "art"
// If category match with myBook categories and the value is true then
return (
<p>{category}</p>
);
});
如果您需要更多信息,请告诉我,我会编辑我的问题。
答案 0 :(得分:3)
您可以使用filter
和find
方法返回新的类别数组,然后使用map
方法返回元素数组。
const allCategories = ["sciencefiction", "manga", "school", "art"];
const myBook = {isItScienceFiction: true, isItManga: false, isItForKids: false}
const result = allCategories.filter(cat => {
const key = Object.keys(myBook).find(k => k.slice(4).toLowerCase() === cat);
return myBook[key]
}).map(cat => `<p>${cat}</p>`)
console.log(result)
您也可以使用reduce
代替filter
和map
和endsWith
方法。
const allCategories = ["sciencefiction", "manga", "school", "art"];
const myBook = {isItScienceFiction: true,isItManga: false,isItForKids: false}
const result = allCategories.reduce((r, cat) => {
const key = Object.keys(myBook).find(k => k.toLowerCase().endsWith(cat));
if(myBook[key]) r.push(`<p>${cat}</p>`)
return r;
}, [])
console.log(result)
答案 1 :(得分:1)
您可以使用
Object.keys(myBook).forEach(function(key){console.log(myBook[key])})
...放置代码而不是console.log
。这可以完成技巧而无需硬编码和最佳实践。
答案 2 :(得分:1)
您实际上不应保留许多包含布尔值的属性。尽管这可能适用于1、2或3个类别,但对于数百个类别而言,效果并不理想。而是将类别存储在数组中:
const myBook = {
categories: ["sciencefiction", "manga", "kids"],
};
如果您已经有了一些具有旧结构的对象,则可以轻松地将它们转换:
const format = old => {
const categories = [];
if(old.isItScienceFiction)
categories.push("sciencefiction");
if(old.isItManga)
categories.push("manga");
if(old.isItForKids)
categories.push("kids");
return { categories };
};
现在要检查一本书是否包含某个类别:
const isManga = myBook.categories.includes("manga");
现在您的渲染也非常简单:
myBook.categories.map(it => <p>{it}</p>)
答案 3 :(得分:1)
您可以为对象的类别和键创建一个Map
:
const allCategories = ["sciencefiction", "manga", "school", "art"],
myBook = { isItScienceFiction:true, isItManga:false, isItForKids:false }
const map = Object.keys(myBook)
.reduce((r, k) => r.set(k.slice(4).toLowerCase(), k), new Map);
/* map:
{"sciencefiction" => "isItScienceFiction"}
{"manga" => "isItManga"}
{"forkids" => "isItForKids"}
*/
allCategories.forEach(key => {
let keyInObject = map.get(key); // the key name in object
let value = myBook[keyInObject]; // value for the key in object
console.log(key, keyInObject, value)
if(keyInObject && value) {
// do something if has the current key and the value is true
}
})
答案 4 :(得分:1)
将Array.filter()
和Array.find()
与RegExp一起使用以找到具有匹配键的类别。使用Array.map()
将类别转换为字符串/ JSX / etc ...
const findMatchingCategories = (obj, categories) => {
const keys = Object.keys(obj);
return allCategories
.filter(category => {
const pattern = new RegExp(category, 'i');
return obj[keys.find(c => pattern.test(c))];
})
.map(category => `<p>${category}</p>`);
};
const allCategories = ["sciencefiction", "manga", "school", "art"];
const myBook = {
isItScienceFiction: true,
isItManga: false,
isItForKids: false
};
const result = findMatchingCategories(myBook, allCategories);
console.log(result);
答案 5 :(得分:1)
您可以尝试这样:
const allCategories = ["sciencefiction", "manga", "school", "art"];
const myBook = {
isItScienceFiction: true,
isItManga: false,
isItForKids: false
};
const myBookKeys = Object.keys(myBook);
const result = allCategories.map(category => {
const foundIndex = myBookKeys.findIndex(y => y.toLowerCase().includes(category.toLowerCase()));
if (foundIndex > -1 && myBook[myBookKeys[foundIndex]])
return `<p>${category}</p>`;
});
console.log(result);
答案 6 :(得分:1)
您可以修改myBook
对象中的键名称,以便于查找,例如:
const allCategories = ["sciencefiction", "manga", "school", "art"];
const myBook = {
isItScienceFiction: true,
isItManga: false,
isItForKids: false
}
const modBook = {}
Object.keys(myBook).map((key) => {
const modKey = key.slice(4).toLowerCase()
modBook[modKey] = myBook[key]
})
const haveCategories = allCategories.map((category) => {
if (modBook[category]) {
return <p>{category}</p>
}
return null
})
console.log(haveCategories)
答案 7 :(得分:1)
无法将sciencefiction
转换为isItScienceFiction
,对于每个myBook
循环category
的所有键也不是最佳选择。
但是将isItScienceFiction
转换为sciencefiction
非常容易,因此您可以从newMyBook
创建myBook
并使用它进行检查。
创建newMyBook
是一次开销。
const allCategories = ["sciencefiction", "manga", "school", "art"];
const myBook = {isItScienceFiction: true,isItManga: false,isItForKids: false};
const newMyBook = Object.keys(myBook).reduce((a, k) => {
return { ...a, [k.replace('isIt', '').toLowerCase()]: myBook[k] };
}, {});
console.log(
allCategories.filter(category => !!newMyBook[category]).map(category => `<p>${category}</p>`)
);