从数组动态获取对象的值

时间:2019-04-11 10:15:28

标签: javascript arrays object

假设我有一个对象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>
    );
});

如果您需要更多信息,请告诉我,我会编辑我的问题。

8 个答案:

答案 0 :(得分:3)

您可以使用filterfind方法返回新的类别数组,然后使用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代替filtermapendsWith方法。

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