假设有数据:
let data = [
{
label: 'Home',
items: [
{ label: 'Dashboard', icon: 'pi pi-fw pi-home', routerLink: ['/'] }
]
},
{
label: 'UI Components',
items: [
{ label: 'Form Layout', icon: 'pi pi-fw pi-id-card', routerLink: ['/uikit/formlayout'] },
{ label: 'Input', icon: 'pi pi-fw pi-check-square', routerLink: ['/uikit/input'] },
{ label: 'Float Label', icon: 'pi pi-fw pi-bookmark', routerLink: ['/uikit/floatlabel'] },
{ label: 'Invalid State', icon: 'pi pi-fw pi-exclamation-circle', routerLink: ['/uikit/invalidstate'] },
{ label: 'Button', icon: 'pi pi-fw pi-mobile', routerLink: ['/uikit/button'], class: 'rotated-icon' },
{ label: 'Table', icon: 'pi pi-fw pi-table', routerLink: ['/uikit/table'] },
]
},
{
label: 'Blocks',
items: [
{ label: 'List', icon: 'pi pi-fw pi-list', routerLink: ['/uikit/list'] },
{ label: 'Tree', icon: 'pi pi-fw pi-share-alt', routerLink: ['/uikit/tree'] },
{ label: 'Panel', icon: 'pi pi-fw pi-tablet', routerLink: ['/uikit/panel'] },
{ label: 'Google', icon: 'pi pi-fw pi-globe', url: ['https://www.google.com'], target: '_blank' },
{ label: 'Bing', icon: 'pi pi-fw pi-comment', url: ['https://www.bing.com'] },
{
label: 'More',
items: [
{ label: 'List', icon: 'pi pi-fw pi-list', routerLink: ['/uikit/list'] },
{ label: 'Google', icon: 'pi pi-fw pi-globe', url: ['https://www.google.com'], target: '_blank' },
{ label: 'Bing', icon: 'pi pi-fw pi-comment', url: ['https://www.bing.com'] },
]
}
]
}
];
后端返回数据:
let badges={
"/uikit/list": "23",
"https://www.google.com": "NEW"
}
需要将数据更新为("/uikit/list"
和 https://www.google.com
只有可能在某个多层嵌套项的 routerLink 或 url 属性中):
let new_data = [
{
label: 'Home',
items: [
{ label: 'Dashboard', icon: 'pi pi-fw pi-home', routerLink: ['/'] }
]
},
{
label: 'UI Components',
items: [
{ label: 'Form Layout', icon: 'pi pi-fw pi-id-card', routerLink: ['/uikit/formlayout'] },
{ label: 'Input', icon: 'pi pi-fw pi-check-square', routerLink: ['/uikit/input'] },
{ label: 'Float Label', icon: 'pi pi-fw pi-bookmark', routerLink: ['/uikit/floatlabel'] },
{ label: 'Invalid State', icon: 'pi pi-fw pi-exclamation-circle', routerLink: ['/uikit/invalidstate'] },
{ label: 'Button', icon: 'pi pi-fw pi-mobile', routerLink: ['/uikit/button'], class: 'rotated-icon' },
{ label: 'Table', icon: 'pi pi-fw pi-table', routerLink: ['/uikit/table'] },
]
},
{
label: 'Blocks',
items: [
{ label: 'List', icon: 'pi pi-fw pi-list', routerLink: ['/uikit/list'], badge: '23' },
{ label: 'Tree', icon: 'pi pi-fw pi-share-alt', routerLink: ['/uikit/tree'] },
{ label: 'Panel', icon: 'pi pi-fw pi-tablet', routerLink: ['/uikit/panel'] },
{ label: 'Google', icon: 'pi pi-fw pi-globe', url: ['https://www.google.com'], target: '_blank', badge: 'NEW' },
{ label: 'Bing', icon: 'pi pi-fw pi-comment', url: ['https://www.bing.com'] },
{
label: 'More',
items: [
{ label: 'List', icon: 'pi pi-fw pi-list', routerLink: ['/uikit/list'], badge: '23' },
{ label: 'Google', icon: 'pi pi-fw pi-globe', url: ['https://www.google.com'], target: '_blank', badge: 'NEW' },
{ label: 'Bing', icon: 'pi pi-fw pi-comment', url: ['https://www.bing.com'] },
]
}
]
}
];
请问除了暴力的用 forEach 一项项遍历还有什么更优雅的做法么?
后端接口无法修改。
1
Kokororin 2022-04-15 00:11:39 +08:00 via iPhone
deepdash
|
2
Leviathann 2022-04-15 00:18:07 +08:00
...那放到 immer 里直接 flatmap 出 item 再遍历改值?
|
3
imycc 2022-04-15 00:19:34 +08:00
这个是描述目录的数据的,每个元素的规则都差不多,用递归处理,好像也不是很麻烦的样子?对于每个元素,碰到有 items 的就递归,没有的就判断 url 或者 routerLink 的值是否为目标值。
|
4
afewok 2022-04-15 00:55:38 +08:00
暴力的方式,难道不是字符串分割和拼接??
以 '/uikit/list'将这坨字符串分割成 2 个字符串,第一个串 + ], badge: '23' +第二个去掉 ], 的串,不就可以了。 |
5
rv54ntjwfm3ug8 OP @afewok #4 哈哈哈最早我也想到了这种方法,就是不便于维护,会被接手的骂
|
6
mxT52CRuqR6o5 2022-04-15 01:25:23 +08:00 via Android
肯定得遍历啊,先序遍历中序遍历后序遍历
|
7
GeruzoniAnsasu 2022-04-15 02:41:40 +08:00
先建倒排索引呗还能咋的,反正只遍历一次
反正架构方案就要求了前端必须完整存储所有 data ,那我为了加速多建几种用于索引的数据结构谁都 blame 不了吧 |
8
mind3x 2022-04-15 02:51:30 +08:00 via Android
jsonpath
|
9
chnwillliu 2022-04-15 06:39:29 +08:00 via Android
这 routerLink 数据量能有多大?上万?十万?遍历抗得住的。
看起来你这是要渲染导航栏,要不就不追求合并 badge 数据到树结构里?渲染导航节点的时候自己拿 url 去那个 map 里查有没有 badge 呗? |
10
ChefIsAwesome 2022-04-15 09:06:41 +08:00
写俩函数,一个是把这种树形对象变成 html 。这样一来,增删改查的操作,可以直接用 dom api 。
<item label icon router> <item label icon router></item> <item label icon router></item> </item> 然后再有一个函数能把这个 html 还原成 js 对象。实际也就遍历一遍,这一个是前面那个反过来而已。 |
11
renmu123 2022-04-15 09:19:48 +08:00 via Android
遍历就完事了
|
13
Rache1 2022-04-15 13:39:49 +08:00 1
前段时间学到的,利用 JSON.parse 的第二个参数,试了一下,效果还可以。
```js var data2 = JSON.parse(JSON.stringify(data), function (k, v) { // 到顶层时返回 if (k === '') { return v } if (k === 'items' && Array.isArray(v)) { v.forEach(function (item) { Object.keys(badges).forEach(function (badge) { // 处理 routerLink if (Array.isArray(item.routerLink) && item.routerLink.includes(badge)) { Object.assign(item, { badge: badges[badge] }) } // 处理 url if (Array.isArray(item.url) && item.url.includes(badge)) { Object.assign(item, { badge: badges[badge] }) } }) }) } return v }) ``` |
14
jjwjiang 2022-04-15 14:08:55 +08:00
遍历有啥不优雅的……直接用 array 的 api 呗
说实话我不是很明白一边觉得遍历不合适一边想着反复序列化反序列化……序列化的开销和不优雅程度可比遍历大多了…… |