根据值跳过数组中的第n个值

时间:2018-07-30 02:55:26

标签: javascript

问题

我正在开发一个图,该图利用{em> samples 的array来构建自身。 不幸的是,该图需要能够调整大小,因此必须必须从图中删除一些样本。

部分解决此问题,我正在使用模数(%)运算符,根据提供的数组跳过提供的数组中的每个 nth 个样本canvas的宽度。因此,假设我们总是 1800 个样本可以使用,并且canvas width 600pxcanvas将跳过每个第三个样本(1800 / 600 = 3)。

这个问题是,如果canvas的宽度为720px,则返回的值将是一个十进制数(准确地说是2.5),而模数不会完全像这样。


代码

JavaScript:

var canvas = document.getElementById("cvs"),
    samples = [ ... ]; // assume there's 1800 samples here between 0-140

var x = 0,
    ctx = canvas.getContext("2d");

// iterate over each of the samples
for(var i = 0; i < samples.length; i++){
    // if there is no remainder when i / (1800 / 720)
    if((i % ((samples.length / canvas.width))) == 0){
        var height = samples[i] * ((canvas.height || 60) / 140);

        // create one bar with appropriate values
        ctx.fillStyle = "red";
        ctx.fillRect(
            x + (x * 2), // left
            (canvas.height || 60) - height, // top
            2, // width
            height // height
        );
        ctx.fill();

        x++;
    }   
}

HTML:

<canvas id="cvs" width="720" height="70"></canvas>

基本上,通过基于canvas width 丢弃 n 个样本,尽可能多地容纳canvas样本。这可能是一些非常简单的数学,但这是到目前为止我能想到的。

感谢所有帮助,欢呼。

1 个答案:

答案 0 :(得分:3)

与其考虑跳过原始文档中的条目,不如考虑从中获取条目。例如,如果您有一个包含五十个项目的数组,并且想将其降采样为20(即2.5的比率),则可以将每2.5个元素取整一次。

function resize(arr, new_size){
    let orig_size = arr.length
    return Array.from({length: new_size}, (_, i) => 
           arr[Math.floor(i * (orig_size + Math.floor(orig_size/new_size))/new_size)])
}

// take 20 from 50
let arr_size = 50
let arr = Array.from({length: arr_size}, (_, i) => i)
console.log(resize(arr, 20))

// take 19 from 29
arr_size = 29
arr = Array.from({length: arr_size}, (_, i) => i)
console.log(resize(arr, 19))

// take 17 from 200
arr_size = 200
arr = Array.from({length: arr_size}, (_, i) => i)
console.log(resize(arr, 17))

请注意,它不会每隔2或3rg花费一次,而是交替进行。这将为您提供任何数组和调整大小值的合理结果。您也可以在函数中进行从0到新长度的for循环,而不是在函数中使用Array.from来获得相同的结果。

编辑:使用for循环推入新数组

function resize(arr, new_size){
    let orig_size = arr.length
    let smaller_array = []
    for (let i = 0; i<new_size; i++){
        let large_array_index = Math.floor(i * (orig_size + Math.floor(orig_size/new_size))/new_size)
        smaller_array[i] = arr[large_array_index]
    }
    return smaller_array
}

// take 20 from 50
let arr_size = 50
let arr = Array.from({length: arr_size}, (_, i) => i)
console.log(resize(arr, 20))