How does one map an array in order to create both a new array with changed array items but without mutating the original array or any of its items?

I have an array of objects for example I want to replace the key normal with value www.test.com/is/images/383773?@HT_dtImage. I am using .replace with regex to basically replace the wid and hei with @HT_dtImage

const urls = [
{"normal": "www.test.com/is/images/383773?wid=200&hei=200", 
"thumbnail": "www.test.com/is/images/383773?wid=200&hei=200"},
{"normal": "www.test.com/is/images/383773?wid=200&hei=200",
 "thumbnail": "www.test.com/is/images/383773?wid=200&hei=200"},
{"normal": "www.test.com/is/images/383773?wid=200&hei=200",
 "thumbnail": "www.test.com/is/images/383773?wid=200&hei=200"}
]

I tried using a .map like this which just returns the original object.

const updateImages = images => {
  images.map(image => {
    return image.normal.replace(/\b(?:wid|hei)=[^&]*&?/g, "") + "@HT_dtImage"
  });
  return images;
};

I also tried this but it returns it in an array without not as an array with objects. I feel like I'm just missing something simple.

const updateImages = images => {
   return images.map(image => {
     return image.normal.replace(/\b(?:wid|hei)=[^&]*&?/g, "") + "@HT_dtImage"
  })
};

The expected output I am looking for is

const urls = [
{"normal": "www.test.com/is/images/383773?@HT_dtImage", 
"thumbnail": "www.test.com/is/images/383773?wid=200&hei=200"},
{"normal": "www.test.com/is/images/383773?@HT_dtImage",
 "thumbnail": "www.test.com/is/images/383773?wid=200&hei=200"},
{"normal": "www.test.com/is/images/383773?@HT_dtImage",
 "thumbnail": "www.test.com/is/images/383773?wid=200&hei=200"}
]


Solution 1:

The OP not only needs to map the original array but also has to create and return a shallow [1] (and accordingly changed) copy of each array item.

[1] which for the OP's use case is sufficient enough due to not having to deal with deeper nested object/data structures.

Thus one could ...

  • either utilize Object.assign
  • or one makes use of spread syntax ...

const getNewListOfUpdatedUrlItems = itemList => {
  return itemList.map(item => {
    return {
      // create shallow `item` copy.
      ...item,
      // change `item` copy's `normal` property accordingly.
      normal: item.normal.replace(/\b(?:wid|hei)=[^&]*&?/g, "@HT_dtImage"),
    };
  });
};

const urlItemList = [{
  "normal": "www.test.com/is/images/383773?wid=200&hei=200",
  "thumbnail": "www.test.com/is/images/383773?wid=200&hei=200",
}, {
  "normal": "www.test.com/is/images/383773?wid=200&hei=200",
  "thumbnail": "www.test.com/is/images/383773?wid=200&hei=200",
}, {
  "normal": "www.test.com/is/images/383773?wid=200&hei=200",
  "thumbnail": "www.test.com/is/images/383773?wid=200&hei=200",
}];
const newUrlItemList = getNewListOfUpdatedUrlItems(urlItemList);

console.log({ newUrlItemList, urlItemList });
.as-console-wrapper { min-height: 100%!important; top: 0; }

In case the OP intentionally wants to mutate every of the original array's url item, then map was not the right method but forEach was ...

function changeUrlNormal(urlItem) {
  urlItem.normal =
    urlItem.normal.replace(/\b(?:wid|hei)=[^&]*&?/g, "@HT_dtImage");
}

const urlItemList = [{
  "normal": "www.test.com/is/images/383773?wid=200&hei=200",
  "thumbnail": "www.test.com/is/images/383773?wid=200&hei=200",
}, {
  "normal": "www.test.com/is/images/383773?wid=200&hei=200",
  "thumbnail": "www.test.com/is/images/383773?wid=200&hei=200",
}, {
  "normal": "www.test.com/is/images/383773?wid=200&hei=200",
  "thumbnail": "www.test.com/is/images/383773?wid=200&hei=200",
}];

urlItemList.forEach(changeUrlNormal);

console.log({ urlItemList });
.as-console-wrapper { min-height: 100%!important; top: 0; }

Solution 2:

  let mapped_urls = urls.map((url) => {
    url.normal.replace(/\b(?:wid|hei)=[^&]*&?/g, '') + '@HT_dtImage';
    return url;
  });

  console.log('URLs', mapped_urls);
      

 const urls = [
    {
      normal: 'www.test.com/is/images/383773?wid=200&hei=200',
      thumbnail: 'www.test.com/is/images/383773?wid=200&hei=200',
    },
    {
      normal: 'www.test.com/is/images/383773?wid=200&hei=200',
      thumbnail: 'www.test.com/is/images/383773?wid=200&hei=200',
    },
    {
      normal: 'www.test.com/is/images/383773?wid=200&hei=200',
      thumbnail: 'www.test.com/is/images/383773?wid=200&hei=200',
    },
  ];

  let mapped_urls = urls.map((url) => {
    url.normal =
      url.normal.replace(/\b(?:wid|hei)=[^&]*&?/g, '') + '@HT_dtImage';
    return url;
  });

  console.log('URLs', mapped_urls);

Here's your output :

enter image description here