如何在 redux 中使用 reselect 过滤数组并检查嵌套对象是否包含 true 值
how to filter through an array and check if a nested object includes a value of true using reselect in redux
我是重新选择的新手,到目前为止,我一直在成功创建选择器,直到我尝试通过嵌套键值对过滤列表。大多数选项都是字符串或字符串数组,它们工作得很好,但我不知道如何通过对象中的 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"
},
我的问题是如何过滤 "maps" 对象和 return 值为 true 的项目?如果这有帮助。我想添加到原始选择器的是 'SHOW_SUMMONERS_RIFT' - "maps": {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
}
}
)
如果这些代码不足以帮助提供解决方案。请让我知道,我可以 post 任何您认为更相关的内容。或者,如果某处有文档,我应该阅读更多……我发现的所有内容都是关于更新嵌套对象的,但我找不到任何关于比较值的信息。请谢谢
解决方案 --- 感谢 Hardik Modha 让我走上了正确的道路。我不知道这是否是最好的解决方案,甚至是使用 Reselect、Redux 甚至普通 javascript 哈哈的好方法,但这是我想出的情况,它适用于基于 a 的选择器嵌套对象
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
您需要操纵您的 1036.maps...
使用 Object.entries()
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/entries
来自文档的示例。
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 })
您只需要先使用 Object.keys
获取所有条目
然后使用 filter
过滤值为 true 的条目
const filtered = Object.keys(map.maps).filter((item) => map.maps[item]);
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]));
});
我是重新选择的新手,到目前为止,我一直在成功创建选择器,直到我尝试通过嵌套键值对过滤列表。大多数选项都是字符串或字符串数组,它们工作得很好,但我不知道如何通过对象中的 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"
},
我的问题是如何过滤 "maps" 对象和 return 值为 true 的项目?如果这有帮助。我想添加到原始选择器的是 'SHOW_SUMMONERS_RIFT' - "maps": {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
}
}
)
如果这些代码不足以帮助提供解决方案。请让我知道,我可以 post 任何您认为更相关的内容。或者,如果某处有文档,我应该阅读更多……我发现的所有内容都是关于更新嵌套对象的,但我找不到任何关于比较值的信息。请谢谢
解决方案 --- 感谢 Hardik Modha 让我走上了正确的道路。我不知道这是否是最好的解决方案,甚至是使用 Reselect、Redux 甚至普通 javascript 哈哈的好方法,但这是我想出的情况,它适用于基于 a 的选择器嵌套对象
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
您需要操纵您的 1036.maps...
使用 Object.entries()
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/entries 来自文档的示例。
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 })
您只需要先使用 Object.keys
获取所有条目
然后使用 filter
const filtered = Object.keys(map.maps).filter((item) => map.maps[item]);
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]));
});