2

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.

Daniel Beck
  • 20,653
  • 5
  • 38
  • 53
  • Can you share what you're having trouble with specifically / your attempt please? – Nick Parsons Apr 21 '21 at 12:43
  • I have to solve a problem in which an object is given .....one of the key in object has array as value so I have to pluralise the name of that key by adding 's' at last of the key name. –  Apr 21 '21 at 12:45
  • @IbrahimAhmed can you share what you've tried? – Nick Parsons Apr 21 '21 at 12:46
  • ```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;``` –  Apr 21 '21 at 12:48
  • I have tried this but this is a hard code I'm assuming that the key with the array value is always placed at index 1. But this is not the case the key with array value is placed randomly in the object. –  Apr 21 '21 at 12:50
  • Reopened as there is more to this problem than just checking if something is an array. Iterating over the object, creating a new object & determining if a key needs to be made plural is all part of the problem. – Nick Parsons Apr 21 '21 at 22:38

2 Answers2

1

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);
Nick Parsons
  • 45,728
  • 6
  • 46
  • 64
0

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);