Reputation: 237
I have an array like this :
const appoint =[
{ a: "asas",
b:{au: false, h:false,l:true}
},
{ a: "avd",
b:{au: true, h:false,l:true}
},
{ a: "as", b:{au: true, h:false,l:false}
}];
When I access b , I want to filter the falsy values, so far I'm not successful doing it with a serie of map() like this :
const result = appoint.map(elem => elem.b.)
const finalresult = result.map(
item =>item.filter(
(item, value)=> item[value] === false )
)
Upvotes: 1
Views: 1205
Reputation: 302
You can do something like this
let array = [{
a: "asas",
b: {
au: false,
h: false,
l: true
}
}, {
a: "avd",
b: {
au: true,
h: false,
l: true
}
}, {
a: "as",
b: {
au: true,
h: false,
l: false
}
}, {
a: "ab",
b: {
au: false,
h: false,
l: false
}
}]
let output = array.filter((element) => {
let keys = Object.keys(element.b)
element.b = keys.filter((key) => {
if (element.b[key]) {
return key
}
})
if (!Object.keys(element.b).length) {
element.b = []
}
return element;
})
console.log(output)
This will give you
[
{
"a": "asas",
"b": [
"l"
]
},
{
"a": "avd",
"b": [
"au",
"l"
]
},
{
"a": "as",
"b": [
"au"
]
},
{
"a": "ab",
"b": []
}
]
I assume you might need an empty array if none of the values are true.
Upvotes: 0
Reputation: 192507
You can create a getKeysBy()
function that takes an object, and a predicate and returns the keys that pass the predicate check.
Now you can use Array.flatMap()
with getKeysBy()
to get an array of all the keys.
const appoint = [{"a":"asas","b":{"au":false,"h":false,"l":true}},{"a":"avd","b":{"au":true,"h":false,"l":true}},{"a":"as","b":{"au":true,"h":false,"l":false}}]
const getKeysBy = (predicate, obj) =>
Object.entries(obj)
.filter(([, v]) => predicate(v))
.map(([k]) => k)
const result = appoint.flatMap(o => getKeysBy(v => v !== false, o.b))
console.log(result)
Upvotes: 1
Reputation: 50326
You can first use map
to get an new array which contains only b
, then use reduce
and inside reduce callback use for..in
to iterate the object and get the keys which is true
const appoint = [{
a: "asas",
b: {
au: false,
h: false,
l: true
}
},
{
a: "avd",
b: {
au: true,
h: false,
l: true
}
},
{
a: "as",
b: {
au: true,
h: false,
l: false
}
}
];
let filtered = appoint.map(function(item) {
return item.b;
}).reduce(function(acc, curr) {
for (let keys in curr) {
if (curr[keys]) {
acc.push(keys)
}
}
return acc;
}, []);
console.log(filtered)
Upvotes: 1
Reputation: 1326
elem.b is an object, not an array, so you can't use filter on it. You could do something like this:
const bArray = appoint.map(elem => elem.b)
const finalresult = bArray.map(b => {
bKeys = Object.keys(b)
const filtered = {}
bKeys.forEach(key => {
if (!b[key]) filtered[key] = false
})
return filtered
})
Upvotes: 1