user8599407
user8599407

Reputation:

How to find out if a key in object has array of values javascript

I'm trying to solve this problem:

In this function you will be provided with an object. That object is storing information on keys. E.g.

{
  name: 'Tom',
  job: ['writing katas', 'marking'],
  favouriteShop: [
    "Paul's Donkey University",
    "Shaq's Taxidermy Shack",
    "Sam's Pet Shop"
  ]
};

In some cases, however, the keys have been very badly named. Good naming convention tells us that the keys containing arrays should be named as plurals.

This function should return a new object that is a copy of the input but with any keys that contain arrays pluralised (an 's' added to the end.) E.g.

{
  name: 'Tom',
  jobs: ['writing katas', 'marking'],
  favouriteShops: [
    "Paul's Donkey University",
    "Shaq's Taxidermy Shack",
    "Sam's Pet Shop"
  ]
}

My attempt:

let cloneObj = Object.assign({},obj);
  let arrayOfKeys = Object.keys(obj);
  if(arrayOfKeys.length === 3){
    let plural = arrayOfKeys[1]+"s"
    cloneObj[plural] = cloneObj[arrayOfKeys[1]];
    delete cloneObj[arrayOfKeys[1]];
  }
  return cloneObj;

Here I'm always pointing the 2nd index key position of object. But here this is not the case the key with array value is placed randomly in the object.

Upvotes: 2

Views: 137

Answers (2)

Vahe Nikoghosyan
Vahe Nikoghosyan

Reputation: 469

I can suggest this option, which will add the s to the object's key, if it does not already have the s ending

const oldObj = { name: 'Tom', job: ['writing katas', 'marking'], favouriteShop: [ "Paul's Donkey University", "Shaq's Taxidermy Shack", "Sam's Pet Shop" ] }


 const betterKeyName = (object) => {
        const obj = {};
        
        Object.entries(object).forEach(([key, value]) => {
            if (value instanceof Array && !String(key).endsWith('s')) {
                obj[`${key}s`] = value
            } else {
                obj[key] = value
            }
        });

        return obj;
    }

const newObj = betterKeyName(oldObj);
console.log(newObj);

Upvotes: 0

Nick Parsons
Nick Parsons

Reputation: 50974

Your current approach has a few issues, the main one is that it doesn't deal with dynamic data, you're instead trying to make your code work for the one object you've been given.
You might find it easier to create a new object from scratch, rather than trying to clone your existing object using Object.assign() and then modifying that by using delete. You can instead build a new object from scratch by grabbing the entries of your object, which will give you a [[key, value], ...] pair array of the form:

[
  ["name", "Tom"],
  ["job", ["writing katas", "marking"]],
  ["favouriteShop", ["Paul's Donkey University", "Shaq's Taxidermy Shack", "Sam's Pet Shop"]]
]

This key-value pair array can then be mapped with .map(), to transform each inner key-value pair. To transform, you can first check if the key needs to be pluralized, by checking if:

  1. The value is an array using Array.isArray()
  2. The key doesn't already end with an "s"

If both of these conditions pass, you can add an "s" to the end of your key value (this is done using the pluralize function below. Once you have. modified the keys of your inner [key, value] pair arrays, you can transform this back into an object by wrapping your mapping function into a call to Object.fromEntries() like so:

const inp = { name: 'Tom', job: ['writing katas', 'marking'], favouriteShop: [ "Paul's Donkey University", "Shaq's Taxidermy Shack", "Sam's Pet Shop" ] };

const pluralize = str => str + (str.endsWith('s') ? '': 's');
const res = Object.fromEntries(Object.entries(inp).map(
  ([key, val]) => [Array.isArray(val) ? pluralize(key) : key, val])
);
console.log(res);

The above logic can be rewritten to use a more imperative approach by using a for...in loop to loop over the keys and the values, and a traditional if-statement to check against the conditions. If you're new to JavaScript, this might be easier to understand than the above (see code comments for details):

const inp = { name: 'Tom', job: ['writing katas', 'marking'], favouriteShop: [ "Paul's Donkey University", "Shaq's Taxidermy Shack", "Sam's Pet Shop" ] };

function pluralize(str) {
  if(str.endsWith('s')) {
    return str;
  } else {
    return str + 's';
  }
} 

const res = {};
for(const key in inp) {
  const value = inp[key]; // get value stored at the current key
  if(Array.isArray(value)) { // if the value is an array:
    const keyPluralized = pluralize(key); //  pluralize the key
    res[keyPluralized] = value; // and add the key to the `res` object
  } else { // value is not an array:. the result
    res[key] = value; // so just add the key and value to
  }
}
console.log(res);

Upvotes: 1

Related Questions