Stark
Stark

Reputation: 593

How to return matched json keys with key?

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

Answers (4)

Andy
Andy

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

Durga
Durga

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

Clinton Yeboah
Clinton Yeboah

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

Felipe Sabino
Felipe Sabino

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

Related Questions