如何做到这一点"怪异的"循环遍历我的数组?

时间:2016-02-04 14:00:06

标签: javascript arrays

我需要在一个简单的数组中循环#34;怪异的"方式。

我的数组的长度总是奇数平方数。

让我们说长度是49.为了更清楚,我的元素是数组的索引。所以我有类似的东西:

myArray = [0, 1, 2, 3, 4 ... 47, 48]

所以,你可以想象下面的方阵:

0   7   14  21  28  35  42
1   8   15  22  29  36  43
2   9   16  23  30  37  44
3   10  17  24  31  38  45
4   11  18  25  32  39  46
5   12  19  26  33  40  47
6   13  20  27  34  41  48

我必须从这个矩阵的中心开始(即myArray[Math.floor(myArray.length / 2)]

在我的示例中:24

然后我必须在左右数字之间交替,直到我通过所有行。

在我的示例中,第一次迭代:17, 31, 10, 38, 3, 45

一旦完成一行,我在向上和向下的数字之间交替,重复给定行的左/右逻辑。

在我的示例中,对于myArray作为输入,我应该按以下顺序循环:

24, 17, 31, 10, 38, 3, 45, 
23, 16, 30, 9, 37, 2, 44,
25, 18, 32, 11, 39, 4, 46,
22, 15, 29, 8, 36, 1, 43,
26, 19, 33, 12, 40, 5, 47,
21, 14, 28, 7, 35, 42, 0,
27, 20, 34, 13, 41, 6, 48

你能帮助我正确实现吗?

这是我到目前为止所做的:https://jsfiddle.net/6qzkk2zx/

8 个答案:

答案 0 :(得分:3)

我建议嵌套两个ES6生成器:

for (let y of outwards(7)) {
    for (let x of outwards(7)) {
        var i = y*7+x;
        use(arr[i]); // for one-dimensional array
        use(arr[x][y]) // for two-dimensional array
    }
}

function* outwards(n) {
    console.assert(n%2 == 1);
    var x = (n-1)/2; // starting in the middle
    yield x;
    for (var i=1; i<n;) {
        x -= i++; // jumping to the left
        yield x;
        x += i++; // and right
        yield x;
    }
}

从此开始,您可以手动将其转换回等效的ES5构造,或者让转换器为您完成工作:Demo

答案 1 :(得分:1)

我想我拥有它:

https://jsfiddle.net/2dbj68t3/2/

var start = (array.length - 1) / 2;
var square = Math.sqrt(array.length);
newArray.push(array[start]);
for (j = 1; j <= Math.floor((square / 2)); j++) {
    newArray.push((array[start - (j * square)]));
    newArray.push((array[start + (j * square)]));
}
for (i = 1; i <= Math.floor((square / 2)); i++) {
    newArray.push((array[start - i]));
    for (j = 1; j <= Math.floor((square / 2)); j++) {
        newArray.push((array[start - i - (j * square)]));
        newArray.push((array[start - i + (j * square)]));
    }
    newArray.push((array[start + i]));
    for (j = 1; j <= Math.floor((square / 2)); j++) {
        newArray.push((array[start + i - (j * square)]));
        newArray.push((array[start + i + (j * square)]));
    }
}

答案 2 :(得分:1)

另一种选择:

// Define number of elements 

var n = 49;

// Calculate center

var start = Math.floor(n / 2);

// Calculate solution

var result = [get_row(start, n)];

for (var l = 1; l < Math.sqrt(n) / 2; l++) {
    result.push(get_row(start - l, n));
    result.push(get_row(start + l, n));    
}

// Print solution

for (var k = 0; k < result.length; k++) {
    console.log(result[k]);
}

///////////////////////////////////////////////

function get_row(c, size) {

    var a = [];
    a.push(c);

    for (var i = 1; i < Math.sqrt(size) / 2; i++) {
        a.push(c - i * Math.sqrt(size));
        a.push(c + i * Math.sqrt(size));
    }

    return a;
}

答案 3 :(得分:1)

这是另一种使用嵌套循环的方法,单个结果数组。

JSfiddle Demo

var num = 7,
    middleElement = Math.floor(num * num / 2); // Square number and get the center number

var result = []; // To store resulting array
for(var j = 1; j <= num; j++) {
    // This will be the middle element, i.e. 24, 23, 25, 22, 26, 21, 27
    // Will be calculated dynamically
    element = j % 2 ? middleElement + Math.floor(j / 2) : middleElement - Math.floor(j / 2);

    result.push(element); // Add middle element in the resulting array
    for(var i = 1; i < num; i++) {
        // For next six elements
        // Get the number from current number
        element = i % 2 ? element - num * i : element + num * i;

        result.push(element);
    }
}

var num = 7,
    middleElement = Math.floor(num * num / 2); // Square number and get the center number

var result = []; // To store resulting array
for(var j = 1; j <= num; j++) {
    // This will be the middle element, i.e. 24, 23, 25, 22, 26, 21, 27
    // Will be calculated dynamically
    element = j % 2 ? middleElement + Math.floor(j / 2) : middleElement - Math.floor(j / 2);

    result.push(element); // Add middle element in the resulting array
    for(var i = 1; i < num; i++) {
        // For next six elements
        // Get the number from current number
        element = i % 2 ? element - num * i : element + num * i;

        result.push(element);
    }
}

console.log(result);

答案 4 :(得分:1)

另一种方法,带有数字位置的数组:

var array = [],                           // 3 2 4 1 5 0 6
    length = 7,
    lower = 0, upper = length - 1,
    result;

while (lower < upper) {                   // generate array
    array.unshift(upper--);
    array.unshift(lower++);
}
lower === upper && array.unshift(upper);

result = Array.apply(null, { length: length }).map(function (_, j) {
    return Array.apply(null, { length: length }).map(function (_, i) {
        return array[i] * length + array[j];
    });
});

document.write('<pre>' + JSON.stringify(result, 0, 4) + '</pre>');

答案 5 :(得分:0)

您正在处理的数字之后的数字(让我们说24)总是将您的数字(24)减去矩阵长度的某个倍数(在您的例如,这个长度是7)。

subject为您正在处理的数字,并hop矩阵的长度。

因此,遍历行,每次迭代两次,总是一次填充两个单元格,第一个填充subject - hop * <counter of iteration>,第二个单元格填充subject + hop * <counter of iteration>

答案 6 :(得分:0)

我希望我理解你的算法,但这应该有效:

如果长度始终为奇数平方,则索引最小值为0,最大值为Sqrt(n + 1)-1。

var verticalup=false;
var horizontalforward=false;
var initial=myArray[Math.floor(myArray.length / 2)];
var maximum=Math.sqrt(myArray.length+1);
var current={vertical:initial,horizontal:initial};
var continue=true;
while (continue) {
    //do something here with the current selection
    if (current.horizontal===0) {
       verticalup=!verticalup;
       current.vertical+=(verticalup?1:-1);
    }
    horizontalforward=!horizontalforward;
    current.horizontal+=(horizontalforward?1:-1);
    continue=current.vertical>=0 && current.vertical<maxima && current.horizontal>=0 && current.horizontal<maximum;
}

答案 7 :(得分:0)

我认为有些内容......

$("form").submit(function(){
    var str = $(this).serialize();
    $.ajax({
        type: 'POST',
        url: 'getResult.php',
        cache: 'false',
        data: str,

        success: function(result){
            alert(result)
        }
    });
    return(false);
});

基本上它利用i和j的奇偶校验来确定是从(中心,中心)点向上还是向下或向左或向右移动。