【问题标题】:Modifying JavaScript array properties修改 JavaScript 数组属性
【发布时间】:2018-04-21 04:27:03
【问题描述】:

我正在使用 Express 并且有一个对象数组。我想修改 created 属性(我使用 dateFormat 包)进行演示。

该数组是 mongo 查询的结果,并分配给变量 stories,如下所示:

[
    { public: false,
      keyStageLevel: [ 'ks1' ],
      created: 2018-03-25T13:01:30.809Z,
      _id: 5ab79daafa832035b416536f,
      slug: 'goldilocks',
      name: 'Goldilocks',
      comments: null,
      id: '5ab79daafa832035b416536f' },
    { public: false,
      keyStageLevel: [ 'ks1' ],
     created: 2018-03-25T13:07:22.421Z,
     _id: 5ab79f0afa832035b4165370,
     slug: 'cinderella',
     name: 'Cinderella',    
     comments: null,
     id: '5ab79f0afa832035b4165370' },
   ..
]

如果我执行

stories.map(function(story){
    story.created = dateFormat(story.created, "dddd, mmmm dS, yyyy, h:MM:ss TT")
    console.log('AFTER TRANSFORM '+story.created);
});

console.log 显示我想要的日期格式,但 stories 数组中的 story.created 值未修改。重新格式化stories 数组中的created 属性的正确方法是什么(如果可能,我正在学习ES5,我发现它更容易理解发生了什么)?

编辑 - 显示 .map.foreach 的查询和使用,这两个都没有修改“故事”

let stories = await Story.find({$or:[{'group': {$in:group}}, 
  {'public':true} ]})
    .populate('group')
    .populate('createdBy');
console.log('BEFORE TRANSFORM '+stories);
// console.log(stories);
// stories.map(function(story){
//     story.created = dateFormat(story.created, "dddd, mmmm dS, yyyy, h:MM:ss TT")
//     console.log('AFTER TRANSFORM '+story.created);
// });
stories.forEach(story => {
    story.created = dateFormat(story.created, "dddd, mmmm dS, yyyy, h:MM:ss TT")
});
console.log('AFTER TRANSFORM '+stories);

【问题讨论】:

  • .map 期望 return 值 - 执行 forEach - stories.forEach(function(story){
  • 假设您没有将stories.map 的结果分配给变量,您在哪里以及如何检查stories 中的值?创建一个最小且可重现的示例。
  • @tymeJV 我同意在这里使用.forEach。但这并不能解释 OP 的问题。因为如果 OP 会执行 stories = stories.map,那么 stories 将是一个仅包含 undefined 的数组,但 OP 表示值不变。如果 OP 真的写了stories.map 而不将新数组分配给变量,那么stories.mapstories.forEach 的结果将是相同的。
  • 我同意@t.niese - 我猜 OP 有更多代码可能会影响我们没有看到的这一点。

标签: javascript arrays node.js express


【解决方案1】:

正如其他人所说,您误用了map。不过,我的选择是正确使用map,并从旧数组创建一个新数组。我认为对未变异的数据进行推理要容易得多。这是一种方法:

const stories = [{"_id": "5ab79daafa832035b416536f", "comments": null, "created": "2018-03-25T13:01:30.809Z", "id": "5ab79daafa832035b416536f", "keyStageLevel": ["ks1"], "name": "Goldilocks", "public": false, "slug": "goldilocks"}, {"_id": "5ab79f0afa832035b4165370", "comments": null, "created": "2018-03-25T13:07:22.421Z", "id": "5ab79f0afa832035b4165370", "keyStageLevel": ["ks1"], "name": "Cinderella", "public": false, "slug": "cinderella"}]

const dateFormat = (d) => d.slice(0, 10) // dummy

const updatedStories = 
    stories.map(story => ({...story, created: dateFormat(story.created)}))

console.log(updatedStories)

如果 ES6 让您感到困扰,那么您可以将其替换为

stories.map(story => Object.assign({}, story, {created: dateFormat(story.created)}))

【讨论】:

  • 非常感谢大家的回答和讨论。我将此标记为答案,因为它对我有用
【解决方案2】:

你可以考虑forEach():

stories.forEach(story => {
    story.created = dateFormat(story.created, "dddd, mmmm dS, yyyy, h:MM:ss TT")
});

文档: Array.prototype.forEach() - JavaScript | MDN

【讨论】:

  • 这不能解释but the story.created values in the stories array is unmodified。如果 return story; 是问题,那么 OP 将有一个 undefined 列表,而不是未更改的故事对象。
  • 这真的是误导。 stories.map 不会更改原始数组,这是真的,但 story.created = ... 仍然会对存储在 stories 中的元素产生影响。所以stories.map(story => { story.created = ... ; return story; }); 和 stories.forEach(story => { story.created = ...; }` 对stories 中元素的story.created 有相同的效果。检查这个jsfiddle
  • .map 返回一个有变化的新数组,而原始数组保持不变您的方法是改变原始数组的对象。
  • @t.niese 我明白你的意思,谢谢你的意见。我已经更新了我的答案。
  • @Ele 感谢您的意见,我已经更新了我的答案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-02-05
  • 2021-09-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多