简体   繁体   English

一个 map 如何创建一个数组以创建一个具有更改数组项但不改变原始数组或其任何项的新数组?

[英]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 .我有一个对象数组,例如我想用值www.test.com/is/images/383773?@HT_dtImage替换键 normal 。 I am using .replace with regex to basically replace the wid and hei with @HT_dtImage我正在使用.replace和正则表达式来基本上用@HT_dtImage替换wid and hei

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.我尝试使用像这样的.map ,它只返回原始的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我正在寻找的预期 output 是

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"}
]

  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:这是您的 output:

在此处输入图像描述

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. OP 不仅需要map原始数组,还必须创建并返回每个数组项的浅[1] (并相应地更改)副本。

[1] which for the OP's use case is sufficient enough due to not having to deal with deeper nested object/data structures. [1]这对于 OP 的用例来说就足够了,因为不必处理更深层次的嵌套对象/数据结构。

Thus one could...这样一来可以...

 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...如果 OP 故意想要改变每个原始数组的 url 项目,那么map不是正确的方法,但forEach是......

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

On your first try, images.map returns a new array which you don't assign to anything.在您第一次尝试时, images.map返回一个您没有分配给任何东西的新数组。 You are returning the same array as the one passed as parameter.您返回的数组与作为参数传递的数组相同。

const newImages = images.map(....);
return newImages

You neen to return an array with some object that have the needed key, so something like:您需要返回一个包含一些具有所需密钥的 object 的数组,例如:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM