1
yiqiao 2021-06-18 16:00:10 +08:00
为什么不直接让后端改下?
|
2
happyCodings OP @yiqiao 后端傻瓜不改 想锤他
|
3
meshell 2021-06-18 16:15:21 +08:00 4
@happyCodings 我觉得这个确实不要后端改,前端自已转换所需要的结构
|
4
AidenChen 2021-06-18 16:21:59 +08:00 4
这个就是要前端改,后端始终提供列表以适应不同的展示需求;这里的处理实质上就是以根节点为最终父级,生成子孙树
|
5
jenlors 2021-06-18 16:23:28 +08:00 3
后端没毛病
|
6
xiangyuecn 2021-06-18 16:28:08 +08:00
后端给平铺展开的数据(一层数组),数据库里面怎么存的就怎么拿,没毛病
结构格式化,js 很容易(简洁),大部分后端语言很困难(蹩脚难看) 你这个递归几行代码就搞定了,也更容易理解,你倒好 for 也不写,reduce 有那么香吗? |
7
TomatoYuyuko 2021-06-18 16:34:09 +08:00 1
这不是前端基本功嘛,生成树,面试都经常会遇到的题,自己写个工具类处理,递归几层就出来了。遇到这种问题不要硬循环,后面维护看到你人都麻了。。
|
8
TomatoYuyuko 2021-06-18 16:38:35 +08:00
前端数据处理直接用 lodash,我记得有现成的方法,你找找
|
9
liyang5945 2021-06-18 16:39:25 +08:00
你这个就两级吗,两级我有个简单的写法
|
10
a719031256 2021-06-18 16:39:32 +08:00
@happyCodings
这个不应该后端改,前几天还在给我配合的前端说这个事情 前端需求变化很快,每次变化都要后端给前端再封装数据,就不方便了,还不如后端反你固定格式数据,前端按实际需求封装自己的需要的格式 |
11
aguesuka 2021-06-18 16:39:44 +08:00
class Address {
/** * @type string */ province /** * @type string */ city /** * @type string */ adcode /** * @type string */ district } class TreeNode { /** * @type string */ value /** * @type string */ label /** * @type TreeNode[] */ children } /** * * @param addresses {Address[]} * @return TreeNode[] */ function dealWithAddressList(addresses) { /** * @type {TreeNode[]} */ const result = [] /** * * @type {Map<string, TreeNode>} */ const createdElements = new Map() /** * * @param value {string} * @param brothers {TreeNode[]} * @returns {TreeNode} */ const nodeOf = (value, brothers) => { let node = createdElements.get(value); if (node === undefined) { node = { children: [], value: value, label: value, } brothers.push(node) createdElements.set(value, node) } return node } for (let address of addresses) { let provinceNode = nodeOf(address.province, result) let cityNode = nodeOf(address.city, provinceNode.children); cityNode.children.push({ children: [], value: address.adcode, label: address.district, }) } return result; } function test() { return dealWithAddressList([{"province": "上海市", "city": "上海市市辖区", "adcode": "310118", "district": "青浦区"}, {"province": "江苏", "city": "苏州市", "adcode": "320506", "district": "吴中区"}, {"province": "山西省", "city": "阳泉市", "adcode": "140302", "district": "城区"}, {"province": "上海市", "city": "上海市市辖区", "adcode": "310101", "district": "黄浦区"}, {"province": "河北省", "city": "石家庄市", "adcode": "130123", "district": "正定县"}]); } test() |
12
zhangchongjie 2021-06-18 16:43:54 +08:00
返回的数据结构如果也是后端改,那一个共用接口得写多少返回类型呀
|
13
ccraohng 2021-06-18 16:48:15 +08:00
function convert() {
const levels = ['province', 'city', 'district']; const result = { children: {}, }; data.forEach((item) => { levels.reduce((map, level) => { const current = item[level]; if (!map.children) { map.children = {}; } map.children[current] = map.children[current] || { data: { label: current, value: level === 'district' ? item.adcode : current, }, }; return map.children[current]; }, result); }); const format = (item) => { if (item.children) { const children = Object.values(item.children).map((child) => { return format(child); }); item.children = children; } return item; }; const root = format(result).children; console.log(root); } convert(); |
14
Vegetable 2021-06-18 16:48:24 +08:00 1
|
15
HashV2 2021-06-18 16:54:57 +08:00
我做后端的时候都是前端来改结构,我做前端的时候都是后端来改结构(因为我比较能喷,而且不怕 delay )
现在我全栈了,哪边简单方便哪边改。。。(现在贼怕 delay,deadline 就是第一生产力) |
16
ryncv 2021-06-18 16:55:33 +08:00
O(1)复杂度
```javascript const data =[{"province":"上海市","city":"上海市市辖区","adcode":"310118","district":"青浦区"}, {"province":"江苏","city":"苏州市","adcode":"320506","district":"吴中区"}, {"province":"山西省","city":"阳泉市","adcode":"140302","district":"城区"}, {"province":"上海市","city":"上海市市辖区","adcode":"310101","district":"黄浦区"}, {"province":"河北省","city":"石家庄市","adcode":"130123","district":"正定县"}]; function listToTree(list) { const map = {}; list.forEach(({province, city, district, adcode}) => { const item = {name: district, value: adcode}; if (!map[province]) { map[province] = { name: province, children: [{ name: city, children: [item] }] } return; } const cityItem = map[province].children.find(one => one.name === city); if (!cityItem) { map[province].children.push({ name: city,children: [item]}) } else { cityItem.children.push(item); } }) return Object.values(map); } console.log(listToTree(data)); ``` |
17
bnm965321 2021-06-18 16:55:49 +08:00
看看 python 的 defaultDict,然后套两层嵌套的 defaultDict 就知道怎么做了
|
18
timedivision 2021-06-18 17:16:38 +08:00
``` js
const data = [ { province: '上海市', city: '上海市市辖区', adcode: '310118', district: '青浦区', }, { province: '江苏', city: '苏州市', adcode: '320506', district: '吴中区' }, { province: '山西省', city: '阳泉市', adcode: '140302', district: '城区' }, { province: '上海市', city: '上海市市辖区', adcode: '310101', district: '黄浦区', }, { province: '河北省', city: '石家庄市', adcode: '130123', district: '正定县', }, ]; const pObj = {}; const cObj = {}; data.forEach(item => { const { province, city } = item; if (pObj[province]) { pObj[province].push(item); } else { pObj[province] = [item]; } if (cObj[city]) { cObj[city].push(item); } else { cObj[city] = [item]; } }); const proValue = Object.values(pObj); const cityKey = Object.keys(cObj); const res = []; proValue.forEach(pro => { cityKey.forEach(key => { if (pro[0] && key === pro[0].city) { res.push({ value: pro[0].adcode, label: pro[0].province, children: [ { label: key, value: pro[0].adcode, children: cObj[key].map(dis => { return { label: dis.district, value: pro[0].adcode, }; }), }, ], }); } }); }); console.log(JSON.stringify(res)); ``` 写的不是很好,但是应该可以满足你的需求 |
19
lumotian 2021-06-18 17:31:52 +08:00
|
20
aitaii 2021-06-18 17:38:55 +08:00
友情提示:可以使用 gist 贴代码,这样代码格式会保留。
|
21
lostpupil 2021-06-18 17:44:40 +08:00
这后端返回的数据中规中矩,说人万恶谈不上。
都是你写的代码属实是辣鸡没错。 你一会儿 each 一会儿 reduce 一会儿 push 你到底想要 mute 还是 immute 你这个用 lodash group map 改一下结构就行了。 |
22
coderJie 2021-06-18 17:57:07 +08:00
我全栈开发,后端转换,前端转换我都试过,开发下来我觉得前端转化更合理。
而且后端只是传了个正常的数据回来怎么就变成屎山代码了? |
23
molvqingtai 2021-06-18 18:00:46 +08:00
前端表示这不是常见的需求嘛
|
24
lostpupil 2021-06-18 18:00:56 +08:00
```javascript
city[ele[name]] = true && item.push({ ``` |
25
lostpupil 2021-06-18 18:01:28 +08:00
是什么原因让你写出了 true && 这种失了智的代码???
|
26
Leviathann 2021-06-18 18:08:00 +08:00 via iPhone
@aitaii 发贴可以选 markdown 模式
|
27
sweetcola 2021-06-18 18:18:11 +08:00
叠 buff 的来了(仅供娱乐)
const data =[{"province":"上海市","city":"上海市市辖区","adcode":"310118","district":"青浦区"}, {"province":"江苏","city":"苏州市","adcode":"320506","district":"吴中区"}, {"province":"山西省","city":"阳泉市","adcode":"140302","district":"城区"}, {"province":"上海市","city":"上海市市辖区","adcode":"310101","district":"黄浦区"}, {"province":"河北省","city":"石家庄市","adcode":"130123","district":"正定县"}]; var obj = Object.keys(obj = data.reduce((t, c) => ({ ...t, [c.province]: { ...t[c.province], [c.city]: { ...t[c.province]?.[c.city], [c.district]: c.adcode } } }), {})).map((v) => ({ name: v, children: Object.keys(obj[v]).map((v1) => ({name: v1, children: Object.keys(obj[v][v1]).map((v2) => ({ name: v2, value: obj[v][v1][v2]})) })) })); console.log(obj); |
28
darknoll 2021-06-18 19:01:28 +08:00
@happyCodings 他不改你帮他改啊
|
29
cking 2021-06-18 19:06:24 +08:00
后端表示 我们不背这锅 这个返回已经算是很好的格式了
|
30
renmu123 2021-06-18 19:36:41 +08:00 via Android
lodash groupby,但应该只支持两级。
|
31
shuoshuxx 2021-06-18 19:43:21 +08:00
后端觉得,这个格式就是正确的,后端不背锅
|
32
Rache1 2021-06-18 20:13:01 +08:00
这些个前端,好不容从切图仔脱离了,又想回到切图仔日子
|
33
learningman 2021-06-18 20:45:08 +08:00
催公司上 GraphQL,想要啥格式有啥格式
|
34
MoYi123 2021-06-18 22:19:44 +08:00
就这样转一下格式都挠破脑袋,用 graphql 不是要被气哭
|
35
Mitt 2021-06-18 22:58:59 +08:00
屎山代码指的是自己写的代码么?😹
|
36
leyviw 2021-06-18 23:26:01 +08:00 via iPhone
后端就是返回标准的格式,给 N 个前端 N 个显示效果用,如果靠后端去兼容前端,那还得了
|
37
aircjm 2021-06-19 00:21:03 +08:00 via Android
喷人家后端代码屎山 自己被喷的老惨了 😓
|
39
medivh 2021-06-19 02:39:43 +08:00
真·前端论坛
|
40
grewer 2021-06-19 09:39:30 +08:00
我看上面觉得后端没问题的不少啊, 这就前端论坛了...
|
41
victor 2021-06-19 10:09:00 +08:00
先甩锅给后端,再来个红包钓鱼
|
42
fewok 2021-06-19 10:30:58 +08:00
就这,什么玩意
|
43
ianva 2021-06-19 11:31:31 +08:00
思路就是错的,代码写的再好也是屎山
接口和 组件 porps 的变化怎么隔离?不隔离接口一变,你代码也跟着变?组件换了这套代码再来一遍?一个需求变化就得重写的东西 另外一个 map 数据的代码有啥值得优化的,明确输入和输出就完了,你代码是屎,别人要重构只了解输入和输出不看你逻辑就行了 |
44
opengps 2021-06-19 11:33:52 +08:00
怪不得前后端互相吐槽,这完全是各自都能处理的,除非这个接口是唯一用途可以后端去修改,否则宁肯提供多个也不应该修改输出结构,因为这种改法不符合开闭原则,是个新老不兼容的改动。前端是 web 还好,前端如果是 app,客户不升级停留在老版本岂不是必须强制下升级了
|
45
ianva 2021-06-19 11:43:06 +08:00
@opengps web 端可以在前端建模隔离接口变化,至于客户端更新的问题,在 BFF 建模隔离接口变化,当然都走 GraphQL 是最方便的
|
46
anguiao 2021-06-19 13:08:14 +08:00 2
这帖子根本不想看,代码可读性太低了🤣
|
47
CokeMine 2021-06-19 14:41:41 +08:00
|
49
LinHoo 2021-06-19 19:17:41 +08:00
const convert = data => {
const options = [] const proviceMap = {} data.forEach(item => { // 没有省 if (!proviceMap[item.province]) { proviceMap[item.province] = { index: options.length, citys: [item.city] } options.push({ value: item.province, label: item.province, children: [ { value: item.city, label: item.city, children: [ { value: item.adcode, label: item.district, } ] } ] }) return } const provinceIndex = proviceMap[item.province].index const cityIndex = proviceMap[item.province].citys.indexOf(item.city) // 没有市 if (cityIndex === -1) { options[provinceIndex].children.push({ value: item.city, label: item.city, children: [ { value: item.adcode, label: item.district, } ] }) return } // 有省有市 options[provinceIndex].children[cityIndex].children.push({ value: item.adcode, label: item.district, }) }) } |
50
DeWjjj 2021-06-20 08:32:54 +08:00
个人认为这个后端出的结构代码没问题,自己解析。
这层级算套的不错的了。 |
51
happyCodings OP @coderJie 大佬我说我写的是 可能表述不清晰
|
52
happyCodings OP |
53
happyCodings OP @aguesuka 谢谢大佬
|
54
happyCodings OP @ccraohng 谢谢大佬
|
55
happyCodings OP @ryncv 谢谢大佬
|
56
happyCodings OP @timedivision 谢谢大佬
|
57
happyCodings OP @CokeMine 谢谢大佬
|
58
happyCodings OP @LinHoo 谢谢大佬
|
59
vueli 2021-06-21 10:05:34 +08:00
为什么不写在。``` ``` 里面, 看着好难受. 又懒不想拿过来运行格式化
|
60
Cy1 2021-06-21 11:08:27 +08:00
后端这格式不是很合理么,真就什么数据都处理好,前端直接套才算合理么?
|