将Javascript原始类型数组分成多个部分

3

我希望能够像以下这样对一个无序的基本类型数组进行分区:

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 // 将数组划分为以 4 开头的部分。

有人知道如何有效地根据第一个数字将此数组进行分段过滤吗?

我知道可以使用 lodash partition 函数处理集合,但是我需要使用原始类型的初始数组以提高速度。即使这样,partition 也只能将数组分成两部分。

提前感谢!


初始数组已经排序了吗? - qwertyuip9
不一定,没有必要。我已经改变了数组的顺序以反映这一点。 - Gerard Simpson
6个回答

2
您可以按照以下步骤操作:

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


1
"

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

1
您可以使用类似于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();

0

如果我错了,请纠正我。你有一个包含整数的数组,比如 [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)});

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


0

这里使用了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]);
}

0
首先,您需要对数组进行排序。您可以以任何方式执行此操作,但是为了这个示例,我将使用快速排序。时间复杂度将为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] ]


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接