Reputation: 10828
I have wrote a script to check any missing fields from the objects and then return Ids of Item that has missing fields.
It is returning:
[ '222', '333' ]
Which I expected to return:
['333']
Why is it returning 222
id as well?
function returnMissingData(items) {
const missing = items.reduce(function(acc, item) {
const fields = [
'Cost',
'Name'
];
for(const key of fields) {
if (!item[key] || item[key] === undefined) {
acc.push(item.Id);
break;
}
}
return acc;
}, []);
return missing;
}
console.log(returnMissingData([
{
Id: "111",
Name: "Name 1",
Cost: 100,
},
{
Id: "222",
Name: "Name 2",
Cost: 0,
},
{
Id: "333",
Name: "Name 3",
}
]));
Edit: It must have properties and it can not be false as Boolean.
Upvotes: 0
Views: 62
Reputation: 171669
Alternate approach using filter/map.
Filter uses Array#some()
to find any missing keys
function returnMissingData(items) {
const fields = ['Cost','Name'];
return items.filter(o => fields.some(k => !(k in o))).map(({Id}) => Id);
}
console.log(returnMissingData([
{
Id: "111",
Name: "Name 1",
Cost: 100,
},
{
Id: "222",
Name: "Name 2",
Cost: 0,
},
{
Id: "333",
Name: "Name 3",
}
]));
Upvotes: 2
Reputation: 8660
Change:
if (!item[key] || item[key] === undefined)
To:
if (item[key] === false || item[key] === undefined)
As you're iterating through your keys you check for !item[key]
- which equates to a check for falsy
values. Falsy values, as implied by the name Fals-y, do not necessarily mean false
. It is the same as saying:
item[key] == false
the above uses type coercion to verify if item[key]
and false
values are analogous. It will change a number
through coercion and then check if it's falsy
. In this case 0
is falsy
.
By using:
item[key] === false
We remove type coercion from the code. It's more sane, and does exactly what you'd expect instead of guessing.
function returnMissingData(items) {
const missing = items.reduce(function(acc, item) {
const fields = [
'Cost',
'Name'
];
for(const key of fields) {
if (item[key] === false || item[key] === undefined) {
acc.push(item.Id);
break;
}
}
return acc;
}, []);
return missing;
}
console.log(returnMissingData([
{
Id: "111",
Name: "Name 1",
Cost: 100,
},
{
Id: "222",
Name: "Name 2",
Cost: 0,
},
{
Id: "333",
Name: "Name 3",
}
]));
Upvotes: 1
Reputation: 1357
Because !item[key]
will be valid for falsy values like 0. As the object with ID 222 has a key with 0 it will match.
Instead, you should check if the object has the key provided with
myObj.hasOwnProperty('key')
function returnMissingData(items) {
const missing = items.reduce(function(acc, item) {
const fields = [
'Cost',
'Name'
];
for(const key of fields) {
if (!item.hasOwnProperty(key) || item[key] === undefined) {
acc.push(item.Id);
break;
}
}
return acc;
}, []);
return missing;
}
console.log(returnMissingData([
{
Id: "111",
Name: "Name 1",
Cost: 100,
},
{
Id: "222",
Name: "Name 2",
Cost: 0,
},
{
Id: "333",
Name: "Name 3",
}
]));
Upvotes: 1
Reputation: 36574
You should use hasOwnProperty()
function returnMissingData(items) {
const missing = items.reduce(function(acc, item) {
const fields = [
'Cost',
'Name'
];
for(const key of fields) {
if (!item.hasOwnProperty(key)) {
acc.push(item.Id);
break;
}
}
return acc;
}, []);
return missing;
}
console.log(returnMissingData([
{
Id: "111",
Name: "Name 1",
Cost: 100,
},
{
Id: "222",
Name: "Name 2",
Cost: 0,
},
{
Id: "333",
Name: "Name 3",
}
]));
Upvotes: 0