let params = { d:9, i:15, s:3, c:15 } // ['i','c'] let params2 = { d:9, i:20, s:3, c:10 } // ['i']
期望返回最大值的 key 的数组, 有没有优雅方式,或者函数式
![]() | 1 hackyuan 2020-07-09 11:51:25 +08:00 写了个不优雅的 ```js const maxKeys = obj => Object.entries(obj).reduce((acc, cur) => { const [key, value] = cur; if (value > acc.max) { acc.max = value; acc.list = [key]; return acc; } if (value === acc.max) { acc.list.push(key); } return acc; }, {max: 0, list: []}).list; maxKeys(params); // ["i", "c"] ``` |
![]() | 2 fe619742721 2020-07-09 11:59:28 +08:00 遍历一次就可以了吧 |
3 misdake 2020-07-09 12:00:04 +08:00 ![]() let max = Math.max(...Object.values(params)); Object.keys(params).filter(key => params[key] === max) // ["i", "c"] |
4 aguesuka 2020-07-09 12:21:21 +08:00 via Android 建议用循环,显然需要一个 variable 当前保存最大值,和一个 mutabl list 保存 key 。不过改成递归应该比较漂亮。 |
![]() | 5 Hanggi 2020-07-09 12:21:39 +08:00 import _ from 'lodash' function getMaxKeys (obj) { return _.keys(obj).filter(key => obj[key] === _.max(_.values(obj))); } result = getMaxKeys(params) |
6 cigmax 2020-07-09 12:24:08 +08:00 via iPhone const maxKeys = Object.entries(params).reduce((acc,cur)=>{if(cur[1]>acc[1]){return [[cur[0]],cur[1]]} else if(cur[1]===acc[1]){return [[...acc[0],cur[0]],cur[1]]}},[[],0]) |
![]() | 7 otakustay 2020-07-09 12:30:08 +08:00 ![]() const maxKeys = Object.entries(array).reduce( ([max, keys], [key, value]) => { if (value > max) { return [value, [key]]; } if (value === max) { return [value, keys.concat(key)]; } return [max, keys]; }, [-Infinity, []] ) |
![]() | 8 Mutoo 2020-07-09 12:32:39 +08:00 import _ from 'lodash'; _.chain(params).toPairs().sortBy(i => -i[1]).filter((v, _, arr) => v[1] === arr[0][1]).map(i => i[0]).value() |
![]() | 9 musi 2020-07-09 12:37:42 +08:00 ![]() ``` let getMaxKeys = obj => Object.keys(obj).map(key => obj[key] == Math.max.apply(null, Object.values(obj)) ? key : null).filter(k => k != null) ``` 貌似还有点不优雅。。。 |
![]() | 10 musi 2020-07-09 12:41:49 +08:00 ![]() @musi 把 map 直接改为 filter 就比较优雅了。 ``` let getMaxKeys = obj => Object.keys(obj).filter(key => obj[key] === Math.max.apply(null, Object.values(obj))) ``` |
![]() | 11 xrr2016 2020-07-09 12:52:58 +08:00 ![]() Object.values(params).sort((a, b) => b - a)[0] |
12 Cbdy 2020-07-09 12:58:48 +08:00 function getMaxValueKeys(params) { const invertedMap = Object.entries(params).reduce((a, c) => (a.set(c[1], [...(a.get(c[1]) || []), c[0]])), new Map) const maxKey = Math.max(...invertedMap.keys()) return invertedMap.get(maxKey) } |
![]() | 13 dartabe 2020-07-09 13:03:08 +08:00 顶一发 filter 感觉函数式有点语义化 瞎用的话没问题 但是不优雅 |
![]() | 14 dartabe 2020-07-09 13:06:38 +08:00 从算法角度 我还是觉得直接 for 吧 |
![]() | 15 yamedie 2020-07-09 13:11:20 +08:00 盲猜 7 楼最优, 更优估计就是原生 for 了 |
16 klesh 2020-07-09 13:21:15 +08:00 Object.keys(params).reduce((k, r) => params[k] > r ? params[k] : r, Number.MIN_VALUE) |
![]() | 17 no1xsyzy 2020-07-09 13:49:46 +08:00 #7 的 keys.concat(key) 可以改成 [...keys, key] |
![]() | 18 Hanggi 2020-07-09 14:11:44 +08:00 ![]() 没看懂你们对优雅的定义。。。 |
![]() | 19 你问的应该叫写法不叫算法 |
20 hupo0 2020-07-09 14:16:10 +08:00 const maxKey = function (o) { const [r] = Object.entries(o).reduce(([r, max], [k, v]) => { switch (Math.sign(v - max)) { case -1: return [r, max]; case 0: return r.push(k), [r, max]; case 1: return [[k], v]; } }); return r; }; |
![]() | 21 ericgui 2020-07-09 14:29:42 +08:00 via Android 怎么写,时间复杂度都是 O(n) 优雅不起来 |
![]() | 22 Tdy95 2020-07-09 14:40:29 +08:00 7 楼+1,我猜楼主的意思是想代码看起来漂亮、短小点? |
23 renmu123 2020-07-09 14:42:56 +08:00 via Android ![]() 我觉得 for 循环最优雅间接,一眼就能看得出来在干啥 |
![]() | 24 wanguorui123 2020-07-09 14:45:03 +08:00 Object.entries(params).filter(item=>item[1] === Math.max(...Object.values(params))).flatMap(item=>item[0]) |
![]() | 25 aaronlam 2020-07-09 15:18:59 +08:00 写法上的优雅应该还是 7 楼的比较优雅把 |
![]() | 26 wanguorui123 2020-07-09 15:19:12 +08:00 var maxKeys = params => Object.entries(params).filter(item=>item[1] === Math.max...Object.values(params))).flatMap(item=>item[0]) |
![]() | 27 source 2020-07-09 15:46:43 +08:00 为啥都在说 7 楼最优。。。 reduce 的回调自由度太大了,很难一眼看出编写者的意图 我第一反应是跟 4 楼一样(除了我是 const 拥护者以外 |
![]() | 28 source 2020-07-09 15:47:27 +08:00 看花了,是 3 楼 |
![]() | 29 otakustay 2020-07-09 15:48:39 +08:00 @source 我同意你的说法,事实上最易读的是写个 for,想要 const 可以来个 const max = {current: 0} 玩 写 reduce 纯粹吧……一种信仰 |
![]() | 30 tiedan 2020-07-09 15:53:07 +08:00 易读算优雅还是代码短算优雅 这是个问题 |
31 roscoecheung1993 2020-07-09 15:56:13 +08:00 可读就 3 楼,追求效率就 for 遍历一趟 |
![]() | 32 takemeaway 2020-07-09 16:03:11 +08:00 ![]() for 循环多简洁明了,整那么多花里胡哨的。 |
33 jackielin 2020-07-09 16:12:57 +08:00 如果用 ramdajs 的话 `R.reduce(R.max, -Infinity, Object.values(params))` 可以解决 |
![]() | 34 alonehat 2020-07-09 16:15:04 +08:00 Object.entries(params).sort(function(a,b){return b[1]-a[1]}).filter(function(item,index,arr){ return item[1]==arr[0][1] }).join('').match(/[a-z]/g) 手动滑稽 |
![]() | 35 chen90902 2020-07-09 17:52:05 +08:00 |
36 brucewar 2020-07-09 17:54:41 +08:00 再简洁的代码,也要保证别人或者自己回头看的时候容易理解 |
37 gdrk 2020-07-09 18:34:28 +08:00 同意三楼,简洁可读性强。 |
![]() | 38 assassin1993zj 2020-07-09 18:50:57 +08:00 @misdake 写的好啊 |
![]() | 39 autoxbc 2020-07-09 18:54:10 +08:00 ![]() for 不够函数式 reduce 心智负担大 写多了就知道,这两个能不用就不用 |
![]() | 40 hanxiV2EX 2020-07-09 19:07:13 +08:00 写 for 吧, 不华丽花哨,看代码的人能一眼看出来就行。 |
![]() | 41 anxiV2EX 2020-07-09 19:18:05 +08:00 我也写了个,没有语法糖的。 function getMaxKeys(obj) { var maxKeys = []; var maxValue = null; for (var k in obj) { var v = obj[k]; if (maxValue === null || v >= maxValue) { if (maxValue !== v) { maxKeys.length = 0; } maxValue = v; maxKeys.push(k); } } return maxKeys; } |
![]() | 42 hanxiV2EX 2020-07-09 19:24:12 +08:00 |
![]() | 43 lovecy 2020-07-09 19:25:43 +08:00 function maxKeys(obj){ let a = []; for (var i in obj) { let v = obj[i]; a[v] || (a[v] = []); a[v].push(i); } return a.pop(); } 大佬们轻喷(^·ω·^ )( ^·ω·^)(^·ω·^ )( ^·ω·^) |
![]() | 44 rioshikelong121 2020-07-09 20:05:33 +08:00 ```Javascript function getMaxKeys(obj){ let maxValue = Math.max(...Object.values(obj)); return Object.entries(obj).reduce((total, cur) => (cur[1] === maxValue ? total.push(cur[0]) : null, total), []); } ``` 我没考虑时间复杂度。 |
![]() | 45 Shy07 2020-07-09 20:43:11 +08:00 |
![]() | 46 rabbbit 2020-07-09 21:34:03 +08:00 function getMaxKeys(obj) { let max = -Infinity; let maxKeys = []; for (const [key, value] of Object.entries(obj)) { if (max < value) { max = value; maxKeys = [key]; } else if (max === value) { maxKeys.push(key); } } return maxKeys; } |
47 lneoi 2020-07-09 23:03:44 +08:00 Object.entries(params).reduce( (max, [key, val]) => ((val === max[0]) ? [max[0], [...max[1], key]] : max) , [Math.max(...Object.values(params)), []] )[1] 来个强行一行的... |
48 nightcatsama 2020-07-10 00:35:18 +08:00 ``` const maxKeys = params => Object.keys(params).reduce((acc, cur, _, []) => !acc.length || params[cur] > params[acc[0]] ? [cur] : params[cur] === params[acc[0]] ? acc.concat([cur]) : acc) ``` 写了个强行一行的,时间复杂度 On 的 |
![]() | 51 hejingyuan199 2020-07-10 07:33:16 +08:00 我想起了 睡觉排序 哈哈 相当优雅 |
![]() | 52 Mutoo 2020-07-10 07:52:31 +08:00 函数式可以非常易读,并且容易理解。 const params = { d: 9, i: 15, s: 3, c: 15 }; const byValueDesc = i => -i[1]; const byHeadValue = (v, _, arr) => v[1] === arr[0][1]; const pickKey = i=>i[0]; _.chain(params) .toPairs() .sortBy(byValueDesc) .filter(filterByHeadValue) .map(pickKey) .value() |
![]() | 54 edk24 2020-07-10 09:34:15 +08:00 ``` function getMaxKey(obj) { const vals = Object.values(obj) const max = Math.max.apply(null, vals) const arr = Object.entries(obj) const retkeys = [] arr.forEach(item =>{ if (item[1] == max) { retkeys.push(item[0]) } }) return retkeys } getMaxKey(params) // [ 'i', 'c' ] getMaxKey(params2) // [ 'i' ] ``` 不优雅的写法... |
![]() | 56 encro 2020-07-10 10:38:26 +08:00 mk= null; for (k in params) { if (mk===null) { mk= k; continue; } mk= params[k]>params[mk] ? k : mk; } return mk; |
57 ZeroShiro 2020-07-10 10:38:41 +08:00 let max = 0; let res = []; for (let key in obj) { if (obj[key] >= max) { if (max !== obj[key]) { res = []; } max = obj[key]; res.push(key); } } return res; 应该可以 |
![]() | 58 anson2017 2020-07-10 10:59:34 +08:00 最简单易懂的话 3 楼 最优是 43 楼吧 |
![]() | 59 woodensail 2020-07-10 11:05:17 +08:00 为什么不试试神奇的 lodash 呢 _.map(_.maxBy(_.toPairs(_.groupBy(_.toPairs(params),_.last)),x=>x[0]|0)[1],_.first) |
![]() | 60 shyling 2020-07-10 11:17:41 +08:00 [Object.entries(a).sort(([a, b], [c,d]) => d - b)[0][0]] 不知道啥叫优雅。。。反正直接排序肯定容易读=-= |
![]() | 61 purensong 2020-07-10 11:18:15 +08:00 43 楼的确实最优了 |
62 wanguorui123 2020-07-10 13:33:35 +08:00 via iPhone 改进版: var maxKeys = params => Object.entries(params).sort((a,b)=>a[1] < b[1] ? 1 : (a[1] > b[1] ? -1 : 0)).filter((e,i,arr)=>arr[0][1] === e[1]).flatMap(e=>e[0]); |
63 buhi 2020-07-10 13:44:21 +08:00 就这个还要讨论这么长一串 搞不懂 |
![]() | 64 Zenyk 2020-07-10 16:40:03 +08:00 建议说 43 最优的先去看看什么叫基数排序 再看看这个排序的适用场景 |