我不确定如何解释这一点,但请耐心等待......
我编写了一个程序,可以创建长度范围为0-4的随机数组,如下所示:[]
或[n]
或[n,n]
或[n,n,n]
或{{1 }}
输入将是1-6之间的随机数字,其中输出[n,n,n,n]
始终是输入的倍数。例如,输入可能是n
,输出可能是2
或[2]
或[4,8]
。
输出将始终从最低值到最高值排序。
输入始终是最低倍数,而最高倍数始终是[2,4,6]
的值。例如,如果输入为input * 4
,则输出范围为3-12或3,6,9和12。
假设,我们说输入是3
,而输出(如果有的话)当然是4的倍数。
唯一可能的输出是......
4
的 []
[4]
[8]
[12]
的 [16]
[4,8]
[4,12]
[4,16]
[8,12]
[8,16]
的 [12,16]
[4,8,12]
[4,8,16]
[4,12,16]
的 [8,12,16]
我想要做的是过滤输出,以便只有上面的粗体数组才有效。除此之外,我想保留所有有效的数组元素,同时删除所有非"线性",渐进元素,如下所示:
[4,8,12,16]
将变为 [4,12]
[4]
将变为 [4,8,16]
[4,8]
将变为 [8,16]
[]
将变为 [8,12,16]
[]
将变为 [12,16]
我终于弄清楚我是如何实现这一目标的,但无论出于何种原因我花了一段时间才能绕过它;所以现在我只是超级好奇。有没有另一种方法来实现这个输出,它明显比下面的代码更有效?是否有可能通过某种循环做同样的事情?是否有任何已知的算法可以解决这类问题?
[]
答案 0 :(得分:2)
因为您的阵列具有固定的长度,所以效率与否并不是真正的问题。
也就是说,可以用更通用的方式编写手工案例区分。这可能会节省一些与数组长度的比较,但最大的好处是它不会硬编码值或假定最大数组长度。
想法。从数组的开头开始,然后,对于每个元素,检查它是否是预期的倍数。如果没有,从那时起切断阵列的其余部分。
function filterMultiples(arr, firstMultiple) {
let badIndex = arr.findIndex((value, index) =>
(value !== (index + 1) * firstMultiple)
);
if (badIndex < 0) {
return arr;
}
return arr.slice(0, badIndex);
}
function test(arr, firstMultiple = 4) {
console.log(
JSON.stringify(arr) + ' is filtered to ' +
JSON.stringify(filterMultiples(arr, firstMultiple)) +
` (multiples of ${firstMultiple})`
);
}
test([4, 8, 16]); // [4, 8]
test([2]); // []
test([4, 6, 12]); // [4]
test([2, 4, 6, 8, 9], 2); // [2, 4, 6, 8]
// tests from question
test([4,12]); // [4]
test([4,8,16]); // [4,8]
test([8,16]); // []
test([8,12,16]); // []
test([12,16]); // []
&#13;
.as-console-wrapper {
max-height: 100% !important;
}
&#13;
上述代码段中的CSS仅用于显示目的,导入部分为filterMultiples
。
解释。我们find the index的第一个元素不是预期值。如果没有找到这样的元素,则所有值都是预期的,我们返回原始数组。否则,我们只返回数组的slice,但不包括第一个意外值。
替代。如果要修改原始数组,可以按如下方式编写函数。
function filterMultiples(arr, firstMultiple) {
let badIndex = arr.findIndex((value, index) =>
(value !== (index + 1) * firstMultiple)
);
if (badIndex >= 0) {
arr.splice(badIndex);
}
}
此方法使用Array#splice
。
答案 1 :(得分:2)
由于Array.prototype.filter中的回调可以处理索引参数,因此可以直接使用它来仅返回“正确”的值。指数:
function filterOnFactor(arr, factor){
return arr.filter((val,i) => ++i * factor == val);
}
//test
for(let arr of [[], [4], [8], [12], [16], [4, 8], [4, 12], [4, 16], [8, 12], [8, 16], [12, 16], [4, 8, 12], [4, 8, 16], [4, 12, 16], [8, 12, 16], [4, 8, 12, 16]]){
console.log(JSON.stringify(arr), '->', JSON.stringify(filterOnFactor(arr,4)));
}
&#13;
注意,这仅在源始终是因子的递增多数时才有效,因此[6,8,12]
仍会返回[8,12]
,但根据信息,源始终以递增的数量生成
只是为了好玩,也是使用生成器功能的解决方案(对所有输入都是安全的)
function* filterOnFactor(arr, factor){
for(let i=0; i< arr.length; i++){
if(arr[i] !== ++i * factor)break;
yield arr[--i];
}
}
//test
for(let arr of [[], [4], [8], [12], [16], [4, 8], [4, 12], [4, 16], [8, 12], [8, 16], [12, 16], [4, 8, 12], [4, 8, 16], [4, 12, 16], [8, 12, 16], [4, 8, 12, 16], [6,8,12]]){
console.log(JSON.stringify(arr), '->', JSON.stringify([...filterOnFactor(arr,4)]));
}
&#13;
答案 2 :(得分:1)
您可以过滤值,然后过滤数组。
function sequence() {
var i = 1;
return function (b) {
return b === factor * i++;
};
}
function validate(a) {
return a.filter(sequence());
}
function notEmpty(a) {
return a.length;
}
var data = [[], [4], [8], [12], [16], [4, 8], [4, 12], [4, 16], [8, 12], [8, 16], [12, 16], [4, 8, 12], [4, 8, 16], [4, 12, 16], [8, 12, 16], [4, 8, 12, 16]],
factor = 4,
result = data
.map(validate)
.filter(notEmpty);
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }