跳至主要內容
  • Hostloc 空間訪問刷分
  • 售賣場
  • 廣告位
  • 賣站?

4563博客

全新的繁體中文 WordPress 網站
  • 首頁
  • js 大佬请赐教优雅算法
未分類
2020 年 7 月 21 日

js 大佬请赐教优雅算法

js 大佬请赐教优雅算法

資深大佬 : coderQiQin 15

let params = {     d:9,     i:15,     s:3,     c:15   }   // ['i','c']    let params2 = {     d:9,     i:20,     s:3,     c:10   }   // ['i'] 

期望返回最大值的 key 的数组, 有没有优雅方式,或者函数式

大佬有話說 (64)

  • 資深大佬 : hackyuan

    写了个不优雅的
    “`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”]
    “`

  • 資深大佬 : fe619742721

    遍历一次就可以了吧

  • 資深大佬 : misdake

    let max = Math.max(…Object.values(params));
    Object.keys(params).filter(key => params[key] === max) // [“i”, “c”]

  • 資深大佬 : aguesuka

    建议用循环,显然需要一个 variable 当前保存最大值,和一个 mutabl list 保存 key 。不过改成递归应该比较漂亮。

  • 資深大佬 : Hanggi

    import _ from ‘lodash’

    function getMaxKeys (obj) {
    return _.keys(obj).filter(key => obj[key] === _.max(_.values(obj)));
    }

    result = getMaxKeys(params)

  • 資深大佬 : cigmax

    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])

  • 資深大佬 : otakustay

    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, []]
    )

  • 資深大佬 : Mutoo

    import _ from ‘lodash’;

    _.chain(params).toPairs().sortBy(i => -i[1]).filter((v, _, arr) => v[1] === arr[0][1]).map(i => i[0]).value()

  • 資深大佬 : musi

    “`
    let getMaxKeys = obj => Object.keys(obj).map(key => obj[key] == Math.max.apply(null, Object.values(obj)) ? key : null).filter(k => k != null)
    “`

    貌似还有点不优雅。。。

  • 資深大佬 : musi

    @musi 把 map 直接改为 filter 就比较优雅了。
    “`
    let getMaxKeys = obj => Object.keys(obj).filter(key => obj[key] === Math.max.apply(null, Object.values(obj)))
    “`

  • 資深大佬 : xrr2016

    Object.values(params).sort((a, b) => b – a)[0]

  • 資深大佬 : Cbdy

    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)
    }

  • 資深大佬 : dartabe

    顶一发 filter 感觉函数式有点语义化 瞎用的话没问题 但是不优雅

  • 資深大佬 : dartabe

    从算法角度 我还是觉得直接 for 吧

  • 資深大佬 : yamedie

    盲猜 7 最优, 更优估计就是原生 for 了

  • 資深大佬 : klesh

    Object.keys(params).reduce((k, r) => params[k] > r ? params[k] : r, Number.MIN_VALUE)

  • 資深大佬 : no1xsyzy

    #7 的 keys.concat(key) 可以改成 […keys, key]

  • 資深大佬 : Hanggi

    没看懂你们对优雅的定义。。。

  • 資深大佬 : KuroNekoFan

    你问的应该叫写法不叫算法

  • 資深大佬 : hupo0

    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;
    };

  • 資深大佬 : ericgui

    怎么写,时间复杂度都是 O(n)
    优雅不起来

  • 資深大佬 : Tdy95

    7 +1,我猜主的意思是想代码看起来漂亮、短小点?

  • 資深大佬 : renmu123

    我觉得 for 循环最优雅间接,一眼就能看得出来在干啥

  • 資深大佬 : wanguorui123

    Object.entries(params).filter(item=>item[1] === Math.max(…Object.values(params))).flatMap(item=>item[0])

  • 資深大佬 : aaronlam

    写法上的优雅应该还是 7 的比较优雅把

  • 資深大佬 : wanguorui123

    var maxKeys = params => Object.entries(params).filter(item=>item[1] === Math.max(…Object.values(params))).flatMap(item=>item[0])

  • 資深大佬 : source

    为啥都在说 7 最优。。。
    reduce 的回调自由度太大了,很难一眼看出编写者的意图
    我第一反应是跟 4 一样(除了我是 const 拥护者以外

  • 資深大佬 : source

    看花了,是 3

  • 資深大佬 : otakustay

    @source 我同意你的说法,事实上最易读的是写个 for,想要 const 可以来个 const max = {current: 0} 玩
    写 reduce 纯粹吧……一种信仰

  • 資深大佬 : tiedan

    易读算优雅还是代码短算优雅 这是个问题

  • 資深大佬 : roscoecheung1993

    可读就 3 ,追求效率就 for 遍历一趟

  • 資深大佬 : takemeaway

    for 循环多简洁明了,整那么多花里胡哨的。

  • 資深大佬 : jackielin

    如果用 ramdajs 的话
    `R.reduce(R.max, -Infinity, Object.values(params))`

    可以解决

  • 資深大佬 : alonehat

    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)

    手动滑稽

  • 資深大佬 : chen90902

    也来试一下 js 大佬请赐教优雅算法

    “`js

    const maxKeys = (obj) =>
    Object.keys(obj).filter(
    (key, _, arr) =>
    obj[key] ===
    Math.max.apply(
    Math,
    arr.map((key) => obj[key])
    )
    );

    “`

  • 資深大佬 : brucewar

    再简洁的代码,也要保证别人或者自己回头看的时候容易理解

  • 資深大佬 : gdrk

    同意三,简洁可读性强。

  • 資深大佬 : assassin1993zj

    @misdake 写的好啊

  • 資深大佬 : autoxbc

    for 不够函数式
    reduce 心智负担大

    写多了就知道,这两个能不用就不用

  • 資深大佬 : hanxiV2EX

    写 for 吧, 不华丽花哨,看代码的人能一眼看出来就行。

  • 資深大佬 : hanxiV2EX

    我也写了个,没有语法糖的。

    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;
    }

  • 資深大佬 : hanxiV2EX

    https://i.loli.net/2020/07/09/hV9Lse3EQ7pfwIg.png

  • 資深大佬 : lovecy

    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();
    }
    大佬们轻喷(^・ω・^ )( ^・ω・^)(^・ω・^ )( ^・ω・^)

  • 資深大佬 : rioshikelong121

    “`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), []);
    }
    “`

    我没考虑时间复杂度。

  • 資深大佬 : Shy07

    https://i.loli.net/2020/07/09/aSFLHGzOXkjrE9d.png

  • 資深大佬 : rabbbit

    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;
    }

  • 資深大佬 : lneoi

    Object.entries(params).reduce(
    (max, [key, val]) => ((val === max[0]) ? [max[0], […max[1], key]] : max)
    , [Math.max(…Object.values(params)), []]
    )[1]

    来个强行一行的…

  • 資深大佬 : nightcatsama

    “`
    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 的

  • 資深大佬 : autoxbc

    @lovecy #43 稀疏数组,这个解法是别致的

  • 資深大佬 : ericgui

    @rabbbit 这是正解

  • 資深大佬 : hejingyuan199

    我想起了 睡觉排序
    哈哈
    相当优雅

  • 資深大佬 : Mutoo

    函数式可以非常易读,并且容易理解。

    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()

  • 資深大佬 : Mutoo

    @Mutoo typo: .filter(byHeadValue)

  • 資深大佬 : edk24

    “`
    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’ ]
    “`

    不优雅的写法…

  • 資深大佬 : source

    @autoxbc #39 完全认同

  • 資深大佬 : encro

    mk= null;
    for (k in params) {
    if (mk===null) {
    mk= k;
    continue;
    }
    mk= params[k]>params[mk] ? k : mk;
    }
    return mk;

  • 資深大佬 : ZeroShiro

    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;

    应该可以

  • 資深大佬 : anson2017

    最简单易懂的话 3
    最优是 43 吧

  • 資深大佬 : woodensail

    为什么不试试神奇的 lodash 呢

    _.map(_.maxBy(_.toPairs(_.groupBy(_.toPairs(params),_.last)),x=>x[0]|0)[1],_.first)

  • 資深大佬 : shyling

    [Object.entries(a).sort(([a, b], [c,d]) => d – b)[0][0]]

    不知道啥叫优雅。。。反正直接排序肯定容易读=-=

  • 資深大佬 : purensong

    43 的确实最优了

  • 資深大佬 : wanguorui123

    改进版:
    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]);

  • 資深大佬 : buhi

    就这个还要讨论这么长一串 搞不懂

  • 資深大佬 : Zenyk

    建议说 43 最优的先去看看什么叫基数排序 再看看这个排序的适用场景

文章導覽

上一篇文章
下一篇文章

AD

其他操作

  • 登入
  • 訂閱網站內容的資訊提供
  • 訂閱留言的資訊提供
  • WordPress.org 台灣繁體中文

51la

4563博客

全新的繁體中文 WordPress 網站
返回頂端
本站採用 WordPress 建置 | 佈景主題採用 GretaThemes 所設計的 Memory
4563博客
  • Hostloc 空間訪問刷分
  • 售賣場
  • 廣告位
  • 賣站?
在這裡新增小工具