Reputation: 593
I'm trying to return and match some keys with a specific value.
If errors keys contain the "password" then I'd like to return only the ones that have password on them, in this case remove the one with firstname_empty.
I came up with this, but even after changing some logic I end up returning the all 3 of them for some reason.
var key = "password";
var errors = [{
"password_empty": "Password is empty",
"firstname_empty": "First name is required",
"password_min": "Password needs a min of 6 chars"
}];
for(var i in errors){
if(errors.match(key)){
console.log(errors[i]);
}
}
Upvotes: 0
Views: 80
Reputation: 63524
There are different ways on how to get the result you want depending on whether you want to preserve your original data structure and return a new one, or whether you want to mutate the original data.
1) Mutate the original data structure - deleting properties from an object.
var errors = [{
"password_empty": "Password is empty",
"firstname_empty": "First name is required",
"password_min": "Password needs a min of 6 chars"
}];
function byKeyword(obj, keyword) {
for (let key in obj) {
if (!key.includes(keyword)) delete obj[key];
}
return [obj];
}
let result = byKeyword(errors[0], 'password');
console.log(result);
2) A simple loop over the object adding matched properties to a temp object.
var errors = [{
"password_empty": "Password is empty",
"firstname_empty": "First name is required",
"password_min": "Password needs a min of 6 chars"
}];
function byKeyword(obj, keyword) {
const temp = {};
for (let key in obj) {
if (key.includes(keyword)) temp[key] = obj[key];
}
return [temp];
}
let result = byKeyword(errors[0], 'password');
console.log(result);
3) Similar to 2 but using reduce
.
var errors = [{
"password_empty": "Password is empty",
"firstname_empty": "First name is required",
"password_min": "Password needs a min of 6 chars"
}];
function byKeyword(obj, keyword) {
return Object.keys(obj).reduce((acc, key) => {
if (key.includes(keyword)) acc[0][key] = obj[key];
return acc;
}, [{}]);
}
let result = byKeyword(errors[0], 'password');
console.log(result);
EDIT: to get the property values only you can use a loop again...
function byKeyword(obj, keyword) {
const temp = [];
for (let key in obj) {
if (key.includes(keyword)) temp.push(obj[key]);
}
return temp;
}
...or reduce
.
function byKeyword(obj, keyword) {
return Object.keys(obj).reduce((acc, key) => {
if (key.includes(keyword)) acc.push(obj[key]);
return acc;
}, []);
}
Hope this was useful.
Upvotes: 1
Reputation: 15614
var key = "password";
var errors = [{
"password_empty": "Password is empty",
"firstname_empty": "First name is required",
"password_min": "Password needs a min of 6 chars"
}];
var resErrors = {};
for(var i in errors[0]){
if(i.match(key)){
resErrors[i] = errors[0][i];
}
}
console.log(resErrors);
You need to math the key, then store if key matched in a new object.
If you have array of object and want to remove the matched key , then loop through the array and in every loop create another object set the values and push to the result array.
var key = "password";
var errors = [{
"password_empty": "Password is empty",
"firstname_empty": "First name is required",
"password_min": "Password needs a min of 6 chars"
}, {
"password_empty": "Password is empty",
"firstname_empty": "First name is required"
}];
var resArr = [];
errors.forEach(function(erorOb) {
var resErrors = {};
for (var i in erorOb) {
if (i.match(key)) {
resErrors[i] = erorOb[i];
}
}
resArr.push(resErrors);
})
console.log(resArr);
Upvotes: 1
Reputation: 245
First things first:
Please make the error object is either an array or an object. After that, it should be easy to loop through it.
Here, I have implemented it as an object.
var key = "password";
var errors = {
"password_empty": "Password is empty",
"firstname_empty": "First name is required",
"password_min": "Password needs a min of 6 chars"
};
for(var err in errors){
if(err.match(key)){
console.log(err);
}
}
The 'for in' retrieves the keys of the object which is safer for testing.
Output:
password_empty
password_min
Upvotes: 0
Reputation: 18215
The answer is not very clear, so I have two options.
if you want to return only the errors that ANY of the keys contain the filtered string, you could try the following
var key = "password";
var errors = [{
"password_empty": "Password is empty",
"firstname_empty": "First name is required",
"password_min": "Password needs a min of 6 chars"
}, {
"does not have it": "any value"
}];
var filtered = errors
.filter(error => Object.keys(error)
.filter(errorKey => errorKey.indexOf(key) >= 0)
.length > 0)
console.log(filtered);
If you also want to filter the error keys that contains the filter word, your could try
var key = "password";
var errors = [{
"password_empty": "Password is empty",
"firstname_empty": "First name is required",
"password_min": "Password needs a min of 6 chars"
}, {
"does not have it": "any value"
}];
var filtered = errors
.map(error => Object.keys(error)
.filter(errorKey => errorKey.indexOf(key) >= 0)
.reduce((error, errorKey, index) => {
error[errorKey] = errors[index][errorKey];
return error;
}, {})
)
.filter(error => Object.keys(error).length > 0)
console.log(filtered);
Upvotes: 0