如何过滤数组并使用redux中的reselect检查嵌套对象是否包含值true

时间:2017-12-17 04:52:45

标签: reactjs redux reselect

我刚刚重新选择,到目前为止我一直在创建选择器方面取得了成功,直到我尝试通过嵌套键值对过滤列表。大多数选项都是字符串或字符串数​​组,它们工作正常,但我无法弄清楚如何通过对象中的true / false值过滤此列表。

这是我的工作选择器到目前为止,json我用它来排序

const getItemsVisibilityFilter = state => state.itemsVisibilityFilter
const getItems = state => state.items

export const getVisibleItems = createSelector(
  [getItemsVisibilityFilter, getItems],
  (itemsVisibilityFilter, items) => {
    switch (itemsVisibilityFilter) {
      case 'SHOW_ALL':
        console.log(items)
        return items
      case 'SHOW_DAMAGE':
        return items.filter(item => item.tags.includes('Damage'))
      case 'SHOW_ATTACK_SPEED':
        return items.filter(item => item.tags.includes('AttackSpeed'))
      case 'SHOW_LIFE_STEAL':
        return items.filter(item => item.tags.includes('LifeSteal'))
      default:
        return items
    }
  }
)

这是JSON中的单个项目

   "1036": {
        "stats": {
            "FlatPhysicalDamageMod": 10
        },
        "description": "<stats>+10 Attack Damage</stats>",
        "gold": {
            "total": 350,
            "sell": 245,
            "base": 350,
            "purchasable": true
        },
        "tags": [
            "Damage",
            "Lane"
        ],
        "plaintext": "Slightly increases Attack Damage",
        "image": {
            "full": "1036.png",
            "group": "item",
            "sprite": "item0.png",
            "h": 48,
            "w": 48,
            "y": 48,
            "x": 48
        },
        "sanitizedDescription": "+10 Attack Damage",
        "maps": {
            "8": true,
            "10": true,
            "11": true,
            "12": true,
            "14": false,
            "16": false,
            "18": true,
            "19": true
        },
        "into": [
            "3077",
            "3123",
            "1053",
            "3155",
            "3134",
            "3133",
            "3034",
            "3035",
            "3044",
            "3052",
            "3072",
            "3122",
            "3144",
            "3252"
        ],
        "id": 1036,
        "name": "Long Sword"
    },

我的问题是如何过滤&#34;地图&#34;对象并返回值为true的项?如果这有帮助。我想要添加到原始选择器的是&#39; SHOW_SUMMONERS_RIFT&#39; - &#34;地图&#34;:{11:true}就像这样

const getItemsVisibilityFilter = state => state.itemsVisibilityFilter
const getItems = state => state.items

export const getVisibleItems = createSelector(
  [getItemsVisibilityFilter, getItems],
  (itemsVisibilityFilter, items) => {
    switch (itemsVisibilityFilter) {
      case 'SHOW_ALL':
        console.log(items)
        return items
      case 'SHOW_DAMAGE':
        return items.filter(item => item.tags.includes('Damage'))
      case 'SHOW_ATTACK_SPEED':
        return items.filter(item => item.tags.includes('AttackSpeed'))
      case 'SHOW_LIFE_STEAL':
        return items.filter(item => item.tags.includes('LifeSteal'))
      case 'SHOW_SUMMONERS_RIFT':
        return items.filter(item => item.maps.includes(I don't know what or to put here to see if 11 === true))
      default:
        return items
    }
  }
)

如果这还没有足够的代码来帮助提供解决方案。请告诉我,我可以发布您认为更相关的任何内容。或者如果某个地方有文档我应该阅读更多...我发现的一切都是关于更新嵌套对象而我无法找到有关比较值的任何内容。拜托,谢谢你

解决方案---感谢Hardik Modha让我走上了正确的道路。我不知道这是最好的解决方案,甚至是使用Reselect,Redux甚至普通javascript的好方法哈哈,但是我提出了这种情况,它适用于基于嵌套对象的选择器

  case 'SHOW_SUMMONERS_RIFT':
    const riftItems = items.filter(item => {
      const mapKey = Object.keys(item.maps)
      const mapValue = Object.values(item.maps)
      if (mapKey[2] && mapValue[2] === true) {
        return item
      }
      return null
    })
    return riftItems

2 个答案:

答案 0 :(得分:3)

您只需要先使用Object.keys获取所有条目 然后使用filter

过滤具有值true的条目

const filtered = Object.keys(map.maps).filter((item) => map.maps[item]);

&#13;
&#13;
const myObject = {
   "1036": {
        "maps": {
            "8": true,
            "10": true,
            "11": true,
            "12": true,
            "14": false,
            "16": false,
            "18": true,
            "19": true
        },
    },
   "1037": {
        "maps": {
            "8": false,
            "10": true,
            "11": true,
            "12": false,
            "14": false,
            "16": false,
            "18": true,
            "19": true
        },
    },
   "1038": {
        "maps": {
            "8": true,
            "10": false,
            "11": true,
            "12": true,
            "14": false,
            "16": false,
            "18": false,
            "19": true
        },
    },
}

Object.keys(myObject).forEach((key) => {
  const maps = myObject[key].maps;
  console.log(Object.keys(maps).filter(item => maps[item]));
});
&#13;
&#13;
&#13;

答案 1 :(得分:0)

你需要操纵你的1036.maps ......

使用Object.entries()

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/entries 来自docs的例子。

const obj = { 0: 'a', 1: 'b', 2: 'c' };
console.log(Object.entries(obj)); // [ ['0', 'a'], ['1', 'b'], ['2', 'c'] ]

你的例子......

let workableData = Object.entries(1036.maps)

workableData.map(ele => { ele[1] === true ? do this : do this })