我试图让这个函数将数组拆分成子集。每个子集的数字应与前一个数字相同,或者与前一个数字相差1。 我下面的例子应该返回两个子集,但它返回{0,1,2,3}。对我做错了什么的想法?此外,是否有更好的方法为每个新子集动态创建一个数组?感谢
function max_tickets() {
var arr = [4, 13, 2, 3];
var myarr = arr.sort(function(a, b){return a-b});
for(var i = 0; i<myarr.length; i++){
var iplus = i+1;
if(i === i || i === iplus){
newArr= [];
newArr.push(i);
}else if (i !== i || i !== iplus){
arr2 =[];
arr2.push(i);
}
}
}
答案 0 :(得分:2)
您尝试做的通常称为“分区”。该问题的通用版本是使用一些“规则”或谓词或条件将数组分区为子数组,该规则指定特定元素应该进入哪个分区,或者指定它应该进入新分区
执行此操作的伪代码为:
To partition an array:
Initialize the resulting array
For each element in the array
If that element starts a new chunk
Create a new empty chunk in the resulting array
Add the element to the most recent chunk
Return the result
这可以在JS中直接表达为
function partition(array, fn) {
return array.reduce((result, elt, i, a) => {
if (!i || !fn(elt, i, a)) result.push([]);
result[result.length - 1].push(elt);
return result;
}, []);
}
现在我们需要写一个函数说明何时应该启动一个新分区:
// Is the element within one of the previous element?
function close(e, i, a) {
return Math.abs(e - a[i-1]) > 1;
}
我们现在可以用
对数组进行分区partition([[4, 13, 2, 3], close)
答案 1 :(得分:1)
这应该有用。
function max_tickets() {
var arr = [4, 13, 2, 3];
var myarr = arr.sort(function (a, b) { return a - b });
arrSubsets = [];
arr1 = [];
for (var i = 0; i < myarr.length; i++) {
if (myarr[i - 1] === undefined) {
arr1.push(myarr[i]);
continue;
}
if (myarr[i] - myarr[i - 1] <= 1) {
arr1.push(myarr[i]);
}
else {
arrSubsets.push(arr1);
arr1 = [];
arr1.push(myarr[i]);
}
}
if (arr1.length > 0)
arrSubsets.push(arr1);
}
max_tickets();
答案 2 :(得分:1)
根据您的问题:
在循环内部,您使用的是i
,就好像它是数组的值一样,但是在您的特定情况下,循环从0
变为myarr.length
的值{{ 1}},以便4
的值为i
。
正如您所看到的,您正在使用0, 1, 2, 3
的值进行比较,而不是使用数组的值来使用数组的值,您必须指定index
,您的案例arrayname[index]
会为您提供值myarr[i]
。
是的,您可以在循环内动态地在另一个数组内创建一个数组:
4, 13, 2, 3
正如您在上一个示例中所看到的,我在var b = [];
for(var i = 0; i < 10; i++){
b.push(['I am' + i, i]);
}
数组内部创建了一个数组,因此一旦循环结束,b
数组内部将有10 b
个每个2个元素。