【问题标题】:Partition Javascript array of primitive types into multiple parts将原始类型的 Javascript 数组划分为多个部分
【发布时间】:2016-08-27 06:06:10
【问题描述】:

我希望能够像这样对原始类型的无序数组进行分区:

var array = [102,103,104,201,203,204,303,301,302,405,406,408,101];

=>

newArray = [[101,102,103,104],[201,203,204],[303,301,302],[405,406,408]]

数组根据第一个整数被分割成段。

数组将根据类似于此表达式的内容进行分区:

array[i]/100|0 === j;

其中 j 可以是 1、2、3 或 4。

例如。 405/100|0 === 4 // partition into the array starting with 4.

有谁知道我可以根据第一个数字有效地将这个数组过滤成多个部分的方法?

我知道我可以将 lodash 分区函数与集合一起使用,但我需要将初始数组作为原始类型以提高速度。即使这样,分区也只会将数组分成两部分。

提前致谢!

【问题讨论】:

  • 初始数组是否已经排序?
  • 不一定,不。我已更改数组的顺序以反映这一点

标签: javascript arrays sorting lodash


【解决方案1】:

你可以这样做;

var arr = [102,103,104,201,203,204,303,301,302,405,406,408,101],
 result = arr.reduce((res,e) => { var idx = e/100|0;
                                  res[idx-1] = res[idx-1] ? res[idx-1].concat(e) : [e];
                                  return res;
                                },[])
             .map(subarr => subarr.sort((a,b) => a-b));
console.log(result);

【讨论】:

    【解决方案2】:

    你可以像这样使用 lodash 函数链

    var array = [404,101,102,103,104,201,203,204,303,301,302,405,406,408];
    var newArray = _(array)
      .groupBy(function (x) { return x / 100 | 0; })
      .values()
      .value();
    

    【讨论】:

      【解决方案3】:

      Array.reduce 似乎被要求:

      var a = [102,103,104,201,203,204,303,301,302,405,406,408,101];
      
      a.reduce (
        function (r, v) { 
          var d = +v.toString ().slice (0,1);
          r[d] && r[d].push (v) || (r[d] = [v]);
          return r; 
        }, [])
      

      【讨论】:

        【解决方案4】:

        如果我错了,请纠正我。您有一个包含整数的数组,例如 [101, 102, 103, 201, 202, 203],并且您希望将其转换为包含以相同整数开头的整数的数组数组,例如 [[101, 102, 103], [201 , 202, 203]]。

        所以,这里有一个简单的解决方案:

        // This object will contain partitioned array
        var newObject = {};
        
        for(var i = 0; i < arr.length; i++) {
          var index = arr[i] / 100;
          if(index in newObj)
            newObj[index].push(arr[i]);
          else
            newObj[index] = [arr[i]];
        }
        

        之后,您将获得一个具有 1,2,3 等属性的对象,该对象将包含从索引 1,2,3 开始的数字数组。

        现在,如果你想要数组数组

        var newArr = [];
        $(newObj).each(function() {newArr.push(this)});
        

        如果您有任何疑问,请告诉我。

        【讨论】:

          【解决方案5】:

          这使用了 lodash 的 groupBy 功能:

          var array = [404,101,102,103,104,201,203,204,303,301,302,405,406,408];
          
          var grouped = _.groupBy(array, function(x) {return x.toString()[0]});
          
          var newArray = []
          for (var key in grouped) {
              newArray.push(grouped[key]);
          }
          

          【讨论】:

            【解决方案6】:

            首先,您需要对数组进行排序。你可以随心所欲地这样做,但在这个例子中,我将使用快速排序。时间复杂度为 O (n * log n)。

            请记住,我在这里或多或少地从头开始做所有事情(不使用内置方法),因此您可以看到它是如何完成的。在学习只使用为你完成所有工作的函数时,我真的觉得它没有帮助,因为那样你就看不到发生了什么。

            从一个未排序的数组开始:

            let unsortedArray = [403, 101, 203, 102, 302, 103, 201, 202, 301, 303, 401, 402];
            

            这是我们的递归快速排序函数:

            let quicksort = arr => {
                    if (arr.length < 2) {
                        return arr;
                }
            
                let pivotIndex = rand(0, arr.length),
                    pivot = arr[pivotIndex],
                    less = [],
                    more = [],
                    sorted = [];
            
                for (let i = 0, len = arr.length; i < len; i++) {
                    if (pivotIndex !== i) {
                        if (arr[i] > pivot) {
                            more.push(arr[i]);
                        } else {
                            less.push(arr[i]);
                        }
                    }
                }
            
                return sorted.concat(quicksort(less)).concat([pivot]).concat(quicksort(more));
            };
            
            let rand = (min, max) => {
                return Math.floor( Math.random() * (min - max) + max );
            };
            

            在未排序的数组上调用函数:

            let sortedArray = quicksort(unsortedArray);
            

            现在我们得到:

            [101, 102, 103, 201, 202, 203, 301, 302, 303, 401, 402, 403]
            

            太好了,现在数组已排序。

            让我们把这个数组分成几组,让它看起来像这样:

            [ [101, 102, 103], [201, 202, 203], [301, 302, 303], [401, 402, 403] ]
            

            使用一点 Redu 的解决方案,这是我们的分区函数:

            let partition = arr => { 
                return arr.reduce((prev, curr) => { 
                    let remainder = curr % 100;
            
                    if (prev[remainder - 1]) {
                        prev[remainder - 1] = prev[remainder - 1].concat(curr);
                    } else {
                        prev[remainder - 1] = [curr];
                    }
            
                    return prev;
                }, []);
            };
            

            现在在排序后的数组上调用分区:

            let partitionedArray = partition(sortedArray);
            

            ...瞧!我们得到[ [101, 102, 103], [201, 202, 203], [301, 302, 303], [401, 402, 403] ]

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2017-01-21
              • 2018-06-12
              • 1970-01-01
              • 2014-03-02
              • 1970-01-01
              相关资源
              最近更新 更多