迭代对象数组并更改每个对象中的一个属性

21

我发现这种模式出现的很多。我从api中得到一个对象数组,并且需要操作其中所有对象的某个属性。

是否有一种使用ES6 / Babel或Typescript更加声明性的方法来实现这种模式?

寻找一些巧妙的解构技巧或类似的东西。

const data = [{ foo: 1, bar: 2}, 
              { foo: 2, bar: 3},
              { foo: 3, bar: 4}];

const increment = a => a + 1;

// Here is my typical pattern
const result = data.map(o => {
    o.foo = increment(o.foo);
    return o;
})

console.log(result);


你需要一个新对象吗? - Nina Scholz
如果您仍然在原地修改旧数组中的对象,那么新数组的意义是什么? - pvg
您IP地址为143.198.54.68,由于运营成本限制,当前对于免费用户的使用频率限制为每个IP每72小时10次对话,如需解除限制,请点击左下角设置图标按钮(手机用户先点击左上角菜单按钮)。 - Richard.Davenport
我想我并没有完全理解“声明式”标准。也就是说,除了直接使用mapforEach之外,还有什么使这更加……某些东西?您是否考虑了另一种语言中的构造? - pvg
5个回答

37

使用阶段 3 预设,Babel中可用的对象展开符 ... 可以很好地完成此操作:

const data = [
  { foo: 1, bar: 2 }, 
  { foo: 2, bar: 3 },
  { foo: 3, bar: 4 },
];

const increment = a => a + 1;

const result = data.map(o => ({ ...o, foo: increment(o.foo) }));
console.log(result);


这仍然不是规格的一部分。 - Hitmands
3
@Hitmands OP特别要求使用Babel的解决方案。 - Jordan Running
他说:“有没有使用ES6/Babel或Typescript的方法,使得该模式更加声明性?” - Hitmands
3
是的,这正是我的回答所展示的。 - Jordan Running
我喜欢使用Object.assign,但这是使用展开运算符的绝佳案例。 - Richard.Davenport

8

我认为这更加优雅 - Object.assign是更新对象中的项目的好方法。

const data = [{
  foo: 1,
  bar: 2
}, {
  foo: 2,
  bar: 3
}, {
  foo: 3,
  bar: 4
}];

const increment = a => a + 1;

// Here is my typical pattern
const result = data.map(o => Object.assign(o, {foo: increment(o.foo)}))

console.log(result);


1
真是太棒了! - Khateeb321
太棒了。完美地运行了。 - Tora Tora Tora

3

如果需要现场版本,可以使用对象键的闭包,并将对象作为参数。

const data = [{ foo: 1, bar: 2 }, { foo: 2, bar: 3 }, { foo: 3, bar: 4 }];
const increment = k => o => o[k]++;

data.forEach(increment('foo'));
console.log(data);


我真的很喜欢这个技巧!我有点担心其他开发人员可能会质疑正在发生什么,但我想这将是一个很好的学习机会! - Richard.Davenport

0

这个怎么样:

data.map(d => (
  Object.assign({}, d, {foo: d.foo + 1})
));


0

Isn't all this completely equivalent to just:

const data = [{ foo: 1, bar: 2 }, { foo: 2, bar: 3 }, { foo: 3, bar: 4 }];

const result = data.slice();
result.forEach(e => e.foo++);
console.log(result);


是的,在这个具体场景中,您确实完全重写了代码,但实际上我并不是在将属性增加1。可能涉及到日期、字符串、具有方法的原型对象等操作。因此,虽然您的答案是正确的,但它实际上并没有回答我的问题。 - Richard.Davenport
@Richard.Davenport 好的,所以这是关于转换本身吗?ES6解构、计算属性名称等可能有所帮助,但如果没有一些关于你正在进行的转换的具体想法,很难具体讨论。forEachmap已经是“声明式”的了(实际上,在你的例子中,由于你正在进行变异而不是映射,你可以认为forEach更加“声明式”)。 - pvg
我认为我们之间存在交流障碍,虽然我们都有自己的看法,这也是大多数问题的所在。你提出了很好的观点,但是你的代码虽然简洁,但阅读起来不太顺畅。这只是我的个人看法。你曾经读过语法错误的推文吗?或者带拉丁文的自命不凡的推文?我们仿佛是用英语沟通,但在语义上遇到了困难。 - Richard.Davenport
error, status code: 429, message: Rate limit reached for default-gpt-3.5-turbo in organization org-HHYtgFtDw4VsdlhuRK1UCbv4 on requests per min. Limit: 3 / min. Please try again in 20s. Contact us through our help center at help.openai.com if you continue to have issues. Please add a payment method to your account to increase your rate limit. Visit https://platform.openai.com/account/billing to add a payment method. - pvg
1
哈哈哈哈,不管你说什么pvg!我觉得我们会很好地合作。 - Richard.Davenport

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接