js 有什么优雅的方法可以在处理 json 数组的时候只改变其中一个键值对的值并且自动保留其他的键值对不变吗

2022-05-12 09:42:53 +08:00
 yuan321
let test=[
  {
    "id": 28620,
    "name": "茌平粉煤灰[Ⅱ级]",
    "dn": "掺合料"
  },
  {
    "id": 5941,
    "name": "粉煤灰[Ⅰ 级]",
    "dn": "掺合料"
  },
  {
    "id": 5226,
    "name": "粉煤灰[Ⅱ级]",
    "dn": "掺合料"
  }]
  //需求是只改变 dn 为其他
  //改变后值为
  test=[
  {
    "id": 28620,
    "name": "茌平粉煤灰[Ⅱ级]",
    "dn": "其他"
  },
  {
    "id": 5941,
    "name": "粉煤灰[Ⅰ 级]",
    "dn": "其他"
  },
  {
    "id": 5226,
    "name": "粉煤灰[Ⅱ级]",
    "dn": "其他"
  }]
 // 这是我用到的方法
  test=test.map((item)=>({
    'id':item.id,
    'name':item.name,
    'dn':'其他'
  }))
  //这种方法是可行但是不优雅,因为就为了改变一个值还要把其他的也写上,有什么更好的方法实现吗?
3399 次点击
所在节点    JavaScript
28 条回复
akaxiaok339
2022-05-12 09:46:47 +08:00
解构呀
noe132
2022-05-12 09:47:26 +08:00
actar
2022-05-12 09:48:13 +08:00
test = test.map((item) => ({
...item,
'dn': '其他'
}))
cjd6568358
2022-05-12 09:49:27 +08:00
test=test.forEach((item)=>item.dn='其他')
--------------------------
JSON.parse(JSON.stringfy(test).replace('dn:xxx','dn:qita'))
alanhe421
2022-05-12 09:51:12 +08:00
跟 json 啥关系?单单数组,做法就是这样,如楼上,缺的是个解构

但假如本身只是个大的字符串,除了 JSON.parse 转为数组,进行处理之外,本身也可以直接 replace 正则。只是不差这点性能了。
yuan321
2022-05-12 10:00:22 +08:00
谢谢,这三种方法都很好
yaphets666
2022-05-12 10:10:24 +08:00
test.forEach(item => item.dn = '其他') 就行了。这里边其实挺有玄机的,值传递~内存,指针~
akatquas
2022-05-12 10:22:42 +08:00
纯纯提问,使用高级语法糖,就是优雅的意思吗?
learningman
2022-05-12 10:25:04 +08:00
@akatquas 函数式编程就是优雅的意思
yuan321
2022-05-12 10:27:10 +08:00
@yaphets666 感觉这种写法确实有点匪夷所思
libook
2022-05-12 10:34:46 +08:00
只改值不改字段,直接循环改值应该是最方便的,如用 forEach 方法或者干脆 for 循环。

涉及到改字段名的话,也可以用循环,然后在每个对象里加个新字段,再 delete 旧字段;或者就用解构。

另外要考虑下文是否还会用到修改之前的数组,如果用到的话也可以在这边新建数组修改,保留原数组的形态。
reiji
2022-05-12 10:39:03 +08:00
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/JSON/parse#%E4%BD%BF%E7%94%A8_reviver_%E5%87%BD%E6%95%B0
如果数据是从服务器拉过来的,可以直接在解析 json 的时候使用 reviver 函数处理
libook
2022-05-12 10:40:42 +08:00
@yuan321 #10 JS 里面赋值有两种情况,一种是 string 、number 、bool 等简单类型的值复制,即 a=1;b=a ,那么 a 和 b 的值都是 1 ,但修改 a 不会导致 b 的值变化;另一种是对象、数组等的引用,即 a=[1];b=a;当给 a push 新元素之后,b 也随之改变。这个是 JS 最常用的基本的原理之一,用熟练了就不会觉得奇怪了。
foolnius
2022-05-12 10:51:05 +08:00
@yuan321 #10
值传递和引用传递的特性,不是 JavaScript 独有的
forbreak
2022-05-12 11:00:03 +08:00
有个 json path 的包,可以用 set('*.dn','其他') 这种方式修改值。但是你这个单层也没必要。 多层 json 的话挺好用。
brader
2022-05-12 11:27:28 +08:00
```
$test = '[{"id":28620,"name":"茌平粉煤灰[Ⅱ级]","dn":"掺合料"},{"id":5941,"name":"粉煤灰[Ⅰ 级]","dn":"掺合料"},{"id":5226,"name":"粉煤灰[Ⅱ级]","dn":"掺合料"}]';
$test = json_decode($test);
foreach ($test as $item) {
$item->dn = '其他';
}
```

用 PHP 吧,少年,哈哈哈
KousukeSakurako
2022-05-12 12:26:40 +08:00
写个 for 循环很麻烦吗
wangtian2020
2022-05-12 13:12:40 +08:00
3 楼 4 楼都是标准答案,应该没有其他不引包的好办法了
我倾向于使用 Array 的 map 或者 forEach
jifengg
2022-05-12 13:35:05 +08:00
用 map 和解构,生生的多出一个数组的内存占用和解构耗时,并且 test 的引用也变了。
forEach 或者 for 才是正解。楼主自己也说了,只是改一个字段的值,为什么要把其他字段也写上呢。

自己简单测试一下,仅仅楼主的三个字段的 obj ,map 耗时是 for[Each]的 10 倍多。
huai
2022-05-12 13:43:38 +08:00
test.forEach(i => i.dn = '其他')

test.map(i => i.dn = '其他') // 只执行,不要考虑返回



原来的值 不在意的话,两种方法没啥区别。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/852327

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX