【问题标题】:How to group the "closest" numbers in an array using javascript如何使用javascript对数组中“最接近”的数字进行分组
【发布时间】:2017-01-19 15:27:04
【问题描述】:

我有一个按升序排序的数字数组。如何对“最接近”的数字进行分组(例如,数字之间的差异小于 5)? 所以从 [1, 4, 5, 23, 40, 55, 56, 100, 234] 我想得到 [[1, 4, 5], 23, 40, [55, 56], 100, 234]

【问题讨论】:

  • 您需要付出一些努力来解决问题,如果您有任何代码,请粘贴您的代码

标签: javascript arrays


【解决方案1】:

您可以检查前任,如果在范围内添加到数组。

var data = [1, 4, 5, 23, 40, 55, 56, 100, 234],
    result = data.reduce(function (r, a, i, aa) {
        if (a - aa[i - 1] < 5) {
            if (!Array.isArray(r[r.length - 1])) {
                r[r.length - 1] = [r[r.length - 1]];
            }
            r[r.length - 1].push(a);
            return r;
        }
        r.push(a);
        return r;
    }, []);

console.log(result); // [[1, 4, 5], 23, 40, [55, 56], 100, 234]

【讨论】:

    【解决方案2】:

    使用Array#reduce方法,将空数组作为初始值,通过检查最后一个元素来更新数组。

    var data = [1, 4, 5, 23, 40, 55, 56, 100, 234];
    
    var res = data.reduce(function(arr, e) {
      // cache last element index
      var i = arr.length - 1;
      // check array exist atleast one element
      if (i > -1) {
        // check last element is array
        if (Array.isArray(arr[i])) {
          // compare last element in array and current element is adjacent
          // if yes push into that array otherwise push into main array
          e - arr[i][arr[i].length - 1] < 5 ? arr[i].push(e) : arr.push(e);
          // if last element is not an array
        } else {
          // if last element and current element is adjacent
          // update last element with an array or just push as usual
          e - arr[i] < 5 ? arr[i] = [arr[i], e] : arr.push(e);
        }
        // if array is empty
      } else
      // simply push the element
        arr.push(e);
      // retuen the array reference
      return arr;
      // set initial value as an epty array
    }, [])
    
    console.log(res);

    【讨论】:

      【解决方案3】:

      另一个(可能更短)减少呢:

       newarray=array.reduce((newarray,number)=>{
         var last=newarray.pop()||[];
            if(last.every(elem=>elem+6>number)){
             last.push(number);
             newarray.push(last);
             return newarray;
            }
             newarray.push(last);
             newarray.push([number]);
             return newarray;
            },[]);
      

      【讨论】:

        【解决方案4】:

        您可以使用 reduce 并检查添加的最后一个元素以添加到最后一个数组或插入新元素,当您到达数据的最后一个元素时,您可以使用 map 删除具有一个元素的数组。

        var data = [1, 4, 5, 23, 40, 55, 56, 100, 234];
        
        var result = data.reduce(function(r, e, i) {
          if (i != 0) {
            (e - data[i - 1] < 5) ? r[r.length - 1].push(e): r.push([e])
          } else {
            r.push([e])
          }
          if (i == data.length - 1) r = r.map(e => e.length == 1 ? e[0] : e)
          return r;
        }, [])
        
        console.log(result)

        【讨论】:

          【解决方案5】:

          这是个好问题...

          虽然我的回答有些复杂,但出于实验目的,您也可以这样做...

          var data = [1, 4, 5, 23, 40, 55, 56, 100, 234],
            result = data.reduce((p,c) => p.length ? p[p.length-1].length ? c-p[p.length-1][p[p.length-1].length-1] < 5 ? (p[p.length-1].push(c),p)
                                                                                                                        : (p.push(c),p)
                                                                          : c-p[p.length-1] < 5 ? (p[p.length-1] = [p[p.length-1],c],p)
                                                                                                : (p.push(c),p)
                                                   : c-p < 5 ? [[p].concat(c)]
                                                             : [p,c]);
          console.log(JSON.stringify(result));

          我认为它也很有效。

          好吧,让我们尝试一些有趣的事情...我们将向该算法提供 1,000,000 个按排序顺序排列的 1 ~ 5,000,000 个随机项目的数组,并测量将它们分组为差异

          var data = Array(1000000).fill()
                                   .map(_ => ~~(Math.random()*5000000)+1)
                                   .sort((a,b) => a-b),
            result = [];
          console.time("grouping");
            result = data.reduce((p,c) => p.length ? p[p.length-1].length ? c-p[p.length-1][p[p.length-1].length-1] < 5 ? (p[p.length-1].push(c),p)
                                                                                                                        : (p.push(c),p)
                                                                          : c-p[p.length-1] < 5 ? (p[p.length-1] = [p[p.length-1],c],p)
                                                                                                : (p.push(c),p)
                                                   : c-p < 5 ? [[p].concat(c)]
                                                             : [p,c]);
          console.timeEnd("grouping");
          console.log(result.length);

          平均大约 200 毫秒。看起来很酷..!

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2022-11-21
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2023-03-20
            • 2016-05-05
            • 2018-12-16
            相关资源
            最近更新 更多