2

I have an array of objects - I want to change one of the object keys to something else without mutating the original array. what is the best method to approach this?

I understand that I could be using the Map method but unsure how this would work. thanks

const books = [
  { title: "To Kill a Mockingbird", writtenBy: "Harper Lee" }, 
  { title: "A Clockwork Orange",  author: "Anthony Burgess" },
  { title: "The Elephant Tree", writtenBy: "R.D. Ronald" } 
]

function changeKey(arr, keyChange, newKey) {

}

// i want to return so the KEY keyChange(author) is changed to newKey(writtenBy)
[
 { title: "To Kill a Mockingbird", writtenBy: "Harper Lee" },
 { title: "A Clockwork Orange",  writtenBy: "Anthony Burgess" },
 { title: "The Elephant Tree", writtenBy: "R.D. Ronald" } 
]
Umair Sarfraz
  • 5,284
  • 4
  • 22
  • 38
Jake
  • 149
  • 2
  • 10
  • 1
    Possible duplicate of [JavaScript: Object Rename Key](https://stackoverflow.com/questions/4647817/javascript-object-rename-key) – PM 77-1 Jun 11 '19 at 22:45
  • Not sure I understand the question: `books` being a const array is 100% irrelevant in this question because you want to change a field in one of the contained objects, so... just change it? `let e = books.find(......); e.writtenBy = e.author; delete e.author;` and done? (using the [Array.find()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/find) function, and if you need to run this on every element, a `forEach` should obviate the need for `find()`) – Mike 'Pomax' Kamermans Jun 11 '19 at 22:47

3 Answers3

0

You can map the parameter array and copy each of the objects within it shallowly using the spread operator. For each new object, if it contains the key we'd like to remove, copy the value to the new key and delete the old key.

const books = [ {title: "To Kill a Mockingbird", writtenBy: "Harper Lee"}, {title: "A Clockwork Orange", author: "Anthony Burgess"}, {title: "The Elephant Tree", writtenBy: "R.D. Ronald"} ];

const changeKey = (arr, keyChange, newKey) =>
  arr.map(e => {
    const o = {...e};
    
    if (keyChange in o) {
      o[newKey] = o[keyChange];
      delete o[keyChange];
    }
    
    return o;
  })
;

console.log(changeKey(books, "author", "writtenBy"));
console.log(books);
ggorlen
  • 44,755
  • 7
  • 76
  • 106
-1

Array helpers like map, filter, reduce, etc doesn't mutate the original array they return a new array. Map receives a function as an argument (callback). Map iterate the array applying your callback in every element.

const books = [ {title: "To Kill a Mockingbird", writtenBy: "Harper Lee"},
                {title: "A Clockwork Orange",  author: "Anthony Burgess"},
                {title: "The Elephant Tree", writtenBy: "R.D. Ronald"} ];

//Function to use as a callback on map
function changeKey(current) {
  if(current.author) return { title: current.title, writtenBy: current.author };
  return current;
}

//Creating new array applying changeKey in every element thanks to map
const newBooks = books.map(changeKey);
console.log(newBooks);
Alejandro
  • 104
  • 4
  • This is a bit weird, since it doesn't create a copy of the objects with no author key. They're not changed within changeKey, so it does correctly answer the question, but if they are changed after they are still the same object. E.G. `delete newBooks[0].title; console.log( books[0] );` – Paul Jun 11 '19 at 23:48
-2

The following will not mutate books array.

const books = [
  { title: "To Kill a Mockingbird", writtenBy: "Harper Lee" },
  { title: "A Clockwork Orange", author: "Anthony Burgess" },
  { title: "The Elephant Tree", writtenBy: "R.D. Ronald" }
];

const renamedBooks = books.map(book => {
  if (book.author) {
    return {
      title: book.title,
      writtenBy: book.author
    };
  }

  return book;
});

console.info(renamedBooks);
Umair Sarfraz
  • 5,284
  • 4
  • 22
  • 38
  • This is a bit weird, since it doesn't create a copy of the objects with no author key. They're not changed within changeKey, so it does correctly answer the question, but if they are changed after they are still the same object. E.G. `delete renamedBooks[0].title; console.log( books[0] );` – Paul Jun 11 '19 at 23:50
  • We don't necessarily need to create a copy or do we? The above answers what is in the question `How to change an objectKey without mutating original array` – Umair Sarfraz Jun 11 '19 at 23:53
  • Yes, I said that it correctly answers the question. It just doesn't answer it well, in my opinion, for the reason I stated. If the OP uses this he may be happy with it thinking it created a copy of every object, and then later they might modify an object in `renamedBooks` not expecting it to affect the objects in `books`, and cause a bug. – Paul Jun 11 '19 at 23:58
  • where is `function changeKey(arr, keyChange, newKey)` asked by the OP ? – Mister Jojo Jun 12 '19 at 00:40
  • Where did OP ask to necessarily include `changeKey()`? IIUC, this is what OP has asked `I have an array of objects - I want to change one of the object keys to something else without mutating the original array. what is the best method to approach this?` – Umair Sarfraz Jun 12 '19 at 00:42