如何使用foreach修改数组数据

时间:2020-10-14 10:01:52

标签: javascript node.js foreach

我从MongoDB中获取数据并使用forEach语句执行。

但是,我想更改2018-08-01T00:00:00.000Z' to 'YYYY-MM中的日期数据。

当我使用Nodejs的Moment包运行console.log时,我想要的数据已打印出来。

console.log(moment(repo.created_at).format("YYYY-MM"))代码通常会输出我想要的数据,但是当另存为repo.created时,原始数据并没有改变。

我不知道如何解决这个问题。

/* GET MyPage Page */
router.get(`/:userId/admin/mypage`, function (req, res, next) {
  let userId = req.params.userId; // UserID Variable
  Repo.find({  // MongoDB
    'owner.login': userId
  }, function (err, repo) {
    if (err) throw err;
    // console.log(repo);
    repo.forEach(function (repo) {

     repo.created_at = moment(repo.created_at).format("YYYY-MM");
      console.log(repo.created_at)
      repo.updated_at = moment(repo.updated_at).format("YYYY-MM");
      console.log(repo.updated_at) 
    })
    res.render('mypage/main', {
      userId: userId,
      dataArray: repo,
    })
  })

当我console.log时,它仍然是这样。

2018-08-01T00:00:00.000Z
2018-09-01T00:00:00.000Z
2018-09-01T00:00:00.000Z
2018-09-01T00:00:00.000Z
2018-09-01T00:00:00.000Z
2018-09-01T00:00:00.000Z
2018-08-01T00:00:00.000Z
2018-09-01T00:00:00.000Z
2017-08-01T00:00:00.000Z

但使用console.log(moment(repo.created_at).format("YYYY-MM"))代码。效果很好

2018-09
2018-09
2018-09
2018-09
2018-09
2018-09
2018-08

3 个答案:

答案 0 :(得分:1)

只需使用.map()

示例:

const updatedRepos = repos.map((repo)=>{
            return {
                ...repo,
                created_at: moment(repo.created_at).format("YYYY-MM");
                updated_at: moment(repo.updated_at).format("YYYY-MM");
            }
    })

答案 1 :(得分:1)

我建议使用映射函数而不是forEach ,因为它通常性能更高并且不会改变原始数组。 (有关code和forEach之间差异的简短演示,请参见codeburst.io上的文章"JavaScript — Map vs. ForEach What’s the difference between Map and forEach in JavaScript?"。)

此外,您应该为参数名称使用不同的名称,因为这可能导致含义混淆。这在JavaScript中被称为“作用域”,它也是“变量阴影”或“名称阴影”的一个示例,并且可能导致细微的错误。因此,应谨慎使用。在您的情况下,您可以命名包含您的repo数组条目的循环参数,例如“ repoElement”,“ repoItem”,“ repoEntry”,或者找到更具描述性的名称。

你也说

但是保存为repo.created时原始数据没有改变

如果执行类似repoItem.created = moment(repoItem.created_at).format("YYYY-MM");的操作,则会向repoItem-object添加一个新属性,但是created_at属性保持不变。在下面的示例中,我将格式日期命名为createdAtupdatedAt,以便创建这些新属性。但是,每个新的repoItem还将在新属性created_atupdated_at旁边提供不变的createdAtupdatedAt属性。

// ...
const dataArray = repo.map(repoItem => ({
    ...repoItem,
    createdAt: moment(repoItem.created_at).format("YYYY-MM"),
    updatedAt: moment(repoItem.updated_at).format("YYYY-MM")
});
res.render('mypage/main', {
  userId,
  dataArray
})
// ...

如果不想包含原始格式的数据,则必须执行另一步骤并销毁所需的数据,然后再将其添加到新对象中。您还可以销毁所有内容,然后删除created_atupdated_at。可以这样完成:

const newRepoItem = { ...repoItem };
delete newRepoItem.created_at;
delete newRepoItem.updated_at;

或使用像这样的“ rest”参数:

const { created_at, updated_at, ...newRepoItem } = repoItem;
// now, you can use the new variable newRepoItem.

有关从对象中删除不需要的属性的更多信息,可以在这里找到:Remove value from object without mutation。 我会使用您和您的团队更好地理解的版本。我认为,关键字delete是使大多数人都更容易理解的解决方案,因为它从字面上说明了它的作用。但是,如果您喜欢分解并习惯了它,那么它可以是更紧凑,更易读的解决方案。不要忘记,这也是有可能的,您的repoItem中只有您关心的几个属性。在这种情况下,您可以破坏要保留的项目。可能类似于以下示例:

// ...
const dataArray = repo.map(repoItem => {
    const { firstPropertyToKeep, secondPropertyToKeep } = repoItem;
    return ({
        firstPropertyToKeep,
        secondPropertyToKeep,
        createdAt: moment(repoItem.created_at).format("YYYY-MM"),
        updatedAt: moment(repoItem.updated_at).format("YYYY-MM")
    });
res.render('mypage/main', {
    userId,
    dataArray
})

我已经创建了一个REPL,您可以在其中查看forEach和map之间的区别:https://repl.it/@helgedrews/forEach-vs-map

我希望这会有所帮助。

答案 2 :(得分:0)

改为使用wt -p "Command Prompt" `; sp -V -p "openSUSE-Leap-15-1" `; sp -H -p "Windows PowerShell"; [void][System.Reflection.Assembly]::LoadWithPartialName('System.Windows.Forms'); Start-Sleep -s 2; [System.Windows.Forms.SendKeys]::SendWait("%{LEFT}"); Start-Sleep -s 2; [System.Windows.Forms.SendKeys]::SendWait("%+{5}") 或设置变量以保存结果

相关问题