29

I am trying to code this in ES6. Below is what I am trying to achieve. Let's say I have an array of objects called schools.

let schools = [
    {name: 'YorkTown', country: 'Spain'},
    {name: 'Stanford', country: 'USA'},
    {name: 'Gymnasium Achern', country: 'Germany'}
];

Now, I want to write a function called editSchoolName which will take 3 parameters, schools (which is the array I have defined above), oldName and name.

I will pass the name of the school in the parameter oldName and that name should be updated with the value in the parameter name.

I don't want to change the state of the variable schools so I am using a map function which will return a new array with the changes.

The editSchoolName function will be called like this -

var updatedSchools = editSchoolName(schools, "YorkTown", "New Gen");

Here, the name YorkTown should be replaced with the name New Gen. So the expected value of the array updatedSchools should be -

let updatedSchools = [
    {name: 'New Gen', country: 'Spain'},
    {name: 'Stanford', country: 'USA'},
    {name: 'Gymnasium Achern', country: 'Germany'}
];

This is how my editSchoolName function looks like -

const editSchoolName = (schools, oldName, name) =>
    schools.map(item => {
        if (item.name === oldName) {
          /* This is the part where I need the logic */
        } else {
          return item;
        }
    });

Need help in making the change in the editSchoolName function to achieve the above mentioned desired result.

Rito
  • 3,092
  • 2
  • 27
  • 40

7 Answers7

30

try this, ES6 Object.assign() to create copy of array element and update new object.

let schools = [{
        name: 'YorkTown',
        country: 'Spain'
    },
    {
        name: 'Stanford',
        country: 'USA'
    },
    {
        name: 'Gymnasium Achern',
        country: 'Germany'
    }
];

const editSchoolName = (schools, oldName, name) => {
    return schools.map(item => {
        var temp = Object.assign({}, item);
        if (temp.name === oldName) {
            temp.name = name;
        }
        return temp;
    });
}

var updatedSchools = editSchoolName(schools, "YorkTown", "New Gen");
console.log(updatedSchools);
console.log(schools);

Using destructuring

const schools = [
  {
    name: "YorkTown",
    country: "Spain",
  },
  {
    name: "Stanford",
    country: "USA",
  },
  {
    name: "Gymnasium Achern",
    country: "Germany",
  },
];
const editSchoolName = (schools, oldName, newName) =>
  schools.map(({ name, ...school }) => ({
    ...school,
    name: oldName === name ? newName : name,
  }));
const updatedSchools = editSchoolName(schools, "YorkTown", "New Gen");
console.log(updatedSchools);
Rahul Sharma
  • 9,534
  • 1
  • 15
  • 37
17

You need to return the updated object:

const editSchoolName = (schools, oldName, name) =>
  schools.map(item => {
      if (item.name === oldName) {
        return {...item, name};
      } else {
        return item;
      }
});
klugjo
  • 19,422
  • 8
  • 57
  • 75
  • 2
    Note that `schools` remain the same. `map` returns a new array. – choz Apr 03 '18 at 10:01
  • 3
    Worth noting that object spread punctuator is not a part of ES2015 (aka ES6). More supported solution would be to desugar it to `Object.assign({}, item, { name })` – Yury Tarabanko Apr 03 '18 at 10:02
  • @YuryTarabanko But also worth noting ES2018 was finalised in January, so should be very safe to use now. Of course transpile for older browsers. – Keith Apr 03 '18 at 10:27
  • @Keith Question tag clearly states `ecmascript-6` :) – Yury Tarabanko Apr 03 '18 at 10:54
  • Hey @klugjo, I tried to implement that but for some reason, it is throwing an error. You can find the code here: https://es6console.com/jfjjqehr/ It's saying unexpected token. Can you help figure out what I am doing wrong? – Rito Apr 03 '18 at 10:56
  • es6console needs updating.. :), For now tick the box Stage-0. @YuryTarabanko Yes, I saw that, and wasn't disagreeing with you, that's why I said `worth pointing out`. For me coding in ES2015, when it's perfectly safe now to code in ES2018 just seems odd. – Keith Apr 03 '18 at 11:05
7
   const editSchoolName = (schools, oldName, newName) =>
    schools.map(({name, ...school }) => ({ ...school, name: oldName === name ? newName : name }));

You could shorten it by using a ternary.

Jonas Wilms
  • 132,000
  • 20
  • 149
  • 151
  • This is the pure functional choice. Because In every iteration a new object is created to the result array. – rodvlopes Sep 18 '18 at 03:03
4

I wonder how come none of the answers give simple solution

const editSchoolName = (schools, oldName, newName) =>
      schools.map(school => { if (school.name === oldName) school.name = newName;
      return school; 
});
Sumer
  • 2,687
  • 24
  • 24
  • 2
    the problem with your code is, that it changes the original array. Because its a reference to the array and its sub-properties, e.g with `school.name = newName` you change the original array's name property... – MMMM Aug 03 '21 at 08:20
3

If you want to edit only the commented part:

const editSchoolName = (schools, oldName, name) =>
    schools.map(item => {
        if (item.name === oldName) {
          var newItem = Object.assign({},item);
          newItem.name = name;
          return newItem;
        }
        else{
          return item;
        }
    });
Anurag Lal
  • 103
  • 7
1

as simple as that:

const editSchoolName = ((schools, oldName, name) =>{
    let results =schools.map((item,index) => { 
        if (item.name === oldName) {
            let newItem = {...item, name} 
            return newItem;
    } else {
        return item;    
    }
    });
    return results;
});
MMMM
  • 3,320
  • 8
  • 43
  • 80
-1

let schools = [{
    name: 'YorkTown',
    country: 'Spain'
  },
  {
    name: 'Stanford',
    country: 'USA'
  },
  {
    name: 'Gymnasium Achern',
    country: 'Germany'
  }
];

let updatedSchools = [{
    name: 'New Gen',
    country: 'Spain'
  },
  {
    name: 'Stanford',
    country: 'USA'
  },
  {
    name: 'Gymnasium Achern',
    country: 'Germany'
  }
];

const editSchoolName = ((schools, oldName, name) =>{
  schools.map(item => {
    if (item.name === oldName) {
      item.name = name;
      return item.name;
    } else {
      return item;
    }
  });
  console.log(schools);
});

editSchoolName(schools, 'YorkTown', "New Gen");
Dipak
  • 2,248
  • 4
  • 22
  • 55