在javascript中重新排序数组

时间:2016-03-12 23:23:11

标签: javascript arrays loops for-loop

假设您有一个这样的数组,我想重新排序它。

$('#elem1, #elem2').nextOrPrev()

我想要做的是循环遍历每个数组,在第一个循环中获取每个数组的第一个值,并将每个数组推送到一个单独的数组中。第二次循环运行时,取每个数组的第二个值,将它们推入单独的数组,依此类推,依此类推。这样单独的数组就像这样;

var myarray = [
    [178, 559, 906, 1252] , [381 , 537 , 937 , 1115] , [346 , 529 , 913 , 1069]
];

我已经循环遍历每个数组并获取所有值,但是无法计算逻辑以仅定位第一个循环的第一个值,第二个循环的第二个等等< / p>

var myNewArray = [178, 381, 346, 559, 537, 529, 906, 937, 913, 1252, 1115, 1069];

这是JSFiddle

4 个答案:

答案 0 :(得分:2)

好了...

也许这太过分了,但是我回家了很长时间,还有一段时间可以杀人。

您的算法问题围绕着您错过了一个步骤。 您实际需要做的是遍历最长阵列的范围。 这意味着您需要创建一个范围(实际范围,或者只知道它的最小/最大边界),从0到所有数组的所有长度的最大值。

当您完成此操作后,您需要经历该范围,并且在该范围内,您需要遍历所有数组的列表(每次迭代循环遍历每个第二维数组)。 /> 对于每个数组,检查它是否在当前索引处有一个元素 如果是,请将其添加到新阵列 第一步(你错过的那一步)几乎就像发牌;你在桌上有4个人,但实际上你在外面而不是4个人中重复了52张牌。

这有很多不同的名字,取决于你正在做什么 这可能是zip一个merge一个rotation(虽然轮换并不能解释扁平化,只是改组)。

所以不用多说,这里有3个解决方案,这些都是不同的 第一个解决方案是更经典的#Java; JavaScript as Java&#34;实现:

&#13;
&#13;
function findMax (arrays) {
  var i = 0;
  var l = arrays.length;
  var max = 0;
  var array = [];

  for (; i < l; i += 1) {
    array = arrays[i];
    max = array.length > max ? array.length : max;
  }

  return max;
}


function rotateAndFlatten (arrays) {

  var flattenedArray = [];

  var maxLength = findMax(arrays);

  var inner = 0;
  var outer = 0;

  var array;
  var currentValue;

  for (; outer < maxLength; outer += 1) {
    for (inner = 0; inner < arrays.length; inner += 1) {
      array = arrays[inner];
      currentValue = array[outer];
      if (currentValue || currentValue === 0) {
        flattenedArray.push(currentValue);
      }
    }
  }

  return flattenedArray;
}



var inputArray = [ [1, 2, 3], [4, 5, 6, 7], [8, 9, 10] ];
var outputArray = rotateAndFlatten(inputArray);

document.querySelector(".ResultInput--ES3").textContent = JSON.stringify(inputArray);
document.querySelector(".ResultOutput--ES3").value = JSON.stringify(outputArray);
&#13;
<div ><pre>Input: <code class="ResultInput ResultInput--ES3"></code></pre></div>
<div ><pre>Output: <code ><output class="ResultOutput ResultOutput--ES3"></output></code></pre></div>
&#13;
&#13;
&#13;

第二种是ES5方式我现在更习惯于使用部分应用的功能来思考,并且一次处理一组操作,而不是手动循环管理的事例:

&#13;
&#13;
function makeRange (min, max) {
  var range = [];
  var i = min;

  while (i < max) {
    range.push(i);
    i += 1;
  }

  return range;
}


function concat (a, b) {
  return a.concat(b);
}


function identity (x) {
  return x;
}


function max (a, b) {
  return b > a ? b : a;
}


function pluck (key) {
  return function pluckFrom (obj) {
    return obj[key];
  };
}


function fillIndexArrays (arrays) {
  return function (i) {
    return arrays.map(pluck(i));
  };
}


function rotateAndFlatten (array) {
  var getLength = pluck("length");
  var maxLength = array.map(getLength).reduce(max, 0);
  var indices = makeRange(0, maxLength);

  return indices.map(fillIndexArrays(array)).reduce(concat, []).filter(identity);
}


var inputArray = [ [1, 2, 3], [4, 5, 6, 7], [8, 9, 10] ];
var outputArray = rotateAndFlatten(inputArray);

document.querySelector(".ResultInput--ES5").textContent = JSON.stringify(inputArray);
document.querySelector(".ResultOutput--ES5").value = JSON.stringify(outputArray);
&#13;
<div ><pre>Input: <code class="ResultInput ResultInput--ES5"></code></pre></div>
<div ><pre>Output: <code ><output class="ResultOutput ResultOutput--ES5"></output></code></pre></div>
&#13;
&#13;
&#13;

这是ES6的版本,它现在可以使用生成器和splat运算符来大大简化范围的构造,并使用lambdas来代码可能被压缩并且同样清晰(对我/我而言)小组):

&#13;
&#13;
const max = (a, b) => b > a ? b : a;
const identity = x => x;
const concat = (a, b) => a.concat(b);

function * range (min, max) {
  let i = min;
  while (i <= max) {
    yield i;
    i += 1;
  }
};


const pluck = (key) => { return (obj) => obj[key]; };


function rotateAndFlatten (arrays) {
  const getLength = pluck("length");
  const maxLength = arrays.map(getLength).reduce(max, 0);

  const indices = [...range(0, maxLength)];

  return indices
    .map(i => arrays.map(pluck(i)))
    .reduce(concat, [])
    .filter(identity);
}


var inputArray = [ [1, 2, 3], [4, 5, 6, 7], [8, 9, 10] ];
var outputArray = rotateAndFlatten(inputArray);

document.querySelector(".ResultInput--ES6").textContent = JSON.stringify(inputArray);
document.querySelector(".ResultOutput--ES6").value = JSON.stringify(outputArray);
&#13;
<div ><pre>Input: <code class="ResultInput ResultInput--ES6"></code></pre></div>
<div ><pre>Output: <code ><output class="ResultOutput ResultOutput--ES6"></output></code></pre></div>
&#13;
&#13;
&#13;

作为奖励,如果我正在编写JS,我就可以实现它,就像我编写的C代码一样,当我必须调试逻辑错误时,我会非常难过(但是切换到快速的算法):

&#13;
&#13;
function init (arrs) {
  var max;
  var i = 0;
  var l = arrs.length;
  var max = 0;
  for (i = 0; i < l; i++)
    if (max < arrs[i].length)
      max = arrs[i].length;

  var j = 0;
  var arr = [];
  for (i = 0; i < max; i++)
    for(j = 0; j < arrs.length; j++)
      if (arrs[j][i] !== undefined)
        arr.push(arrs[j][i]);

  document.querySelector(".ResultOutput--C").value = JSON.stringify(arr);
}

var arrs = [ [1, 2, 3], [4, 5, 6, 7], [8, 9, 10] ];
document.querySelector(".ResultInput--C").textContent = JSON.stringify(arrs);
init(arrs);
&#13;
<div ><pre>Input: <code class="ResultInput ResultInput--C"></code></pre></div>
<div ><pre>Output: <code ><output class="ResultOutput ResultOutput--C"></output></code></pre></div>
&#13;
&#13;
&#13;

希望能为您提供一些可以咀嚼的东西,以及对可能正在发挥作用的低级算法的深入了解,以及实现这些低级算法的更高级别的方法。

答案 1 :(得分:1)

或者您也可以这样做:.shift()返回first item的{​​{1}},但请注意此解决方案将array原始数组

alter

答案 2 :(得分:1)

不是在外部循环中迭代myarray,而是在内部循环中迭代每个子数组,而应该反过来。然后它有点棘手,因为外部循环迭代子数组,但它们可以有不同的长度。我添加了done变量以了解停止的位置。

var myNewArray = [];
for(var i=0, done=false; !done; ++i) {
  done = true;
  for(var j=0; j<myarray.length; ++j) {
    if(i < myarray[j].length) {
      done = false;
      myNewArray.push(myarray[j][i]);
    }
  }
}

答案 3 :(得分:0)

Lodash有一个名为zip的方法可以完成你想做的事情。

console.log(_.zip(myarray)); // [[178, 381, 346], [559, 537, 529], [906, 937, 913], [1252, 1115, 1069]]