如何将数组分成随机对数组(无重复)?

时间:2018-05-26 12:35:59

标签: javascript

我有一组2N元素。例如,[1,2,3,4,5,6,7,8]。 现在我想把它分成一组随机对(没有重复)。 结果可能是:

[[1,3],[2,5],[4,8],[6,7]]

我尝试编码,但我认为它不好。有更好的想法吗?

function arrSlice(arr) {
  if (arr.length % 2 !== 0) return 0;
  var
    newArr = [],
    //temp array.
    tmpArr = [];
  for (let i = 0; i < arr.length; i++) {
    if (!tmpArr.includes(arr[i])) {
      var rndIndex;
      do {
        rndIndex = Math.floor(Math.random() * (arr.length - (i + 1))) + (i + 1);
      } while (tmpArr.includes(arr[rndIndex]));
      newArr.push([arr[i], arr[rndIndex]]);
      tmpArr.push(arr[i]);
      tmpArr.push(arr[rndIndex]);
    }
  }
  return newArr;
}

var arr = [1, 2, 3, 4, 5, 6, 7, 8]
console.log(arrSlice(arr));

5 个答案:

答案 0 :(得分:1)

你可以创建两个函数,一个用于返回新的混洗数组,另一个用于对其进行切片。

const arr = [1, 2, 3, 4, 5, 6, 7, 8];

function shuffle(arr) {
  return arr.reduce((r, e, i) => {
    r.splice(Math.random() * (i + 1), 0, e);
    return r;
  }, [])
}

function sliceArray(data, n = 2) {
  const arr = [];
  for (var i = 0; i < data.length; i += n) arr.push(data.slice(i, i + n))
  return arr;
}

const result = sliceArray(shuffle(arr), 2);
console.log(JSON.stringify(result))

这是另一种方法,您可以先生成新的空数组子数组,然后循环数据,同时还有剩余元素并填充空数组。

function create(data, len) {
  data = data.slice();
  const result = Array.from(Array(Math.ceil(data.length / len)), () => []);
  let aN = 0;

  while (data.length) {
    result[aN].push(data.splice(parseInt(Math.random() * data.length), 1)[0]);
    if (result[aN].length == len) aN++;
  }

  return result;
}

console.log(JSON.stringify(create([1, 2, 3, 4, 5, 6, 7, 8], 2)))
console.log(JSON.stringify(create([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 3)))

答案 1 :(得分:1)

我只是从数组中删除随机元素并将它们成对添加:

childNodes

或者,这是生成器的一个很好的用例:

const random = end => Math.floor(Math.random() * end);

function pairedShuffle(array) {      
  const remove = () => array.splice(random(array.length), 1)[0];

  const result = [];
  while(array.length >= 2)
    result.push([remove(), remove()]);
  return result;
}

可用作:

function* pairs(iterable) {
  let prev = null;
  let i = 0;
  for(const el of iterable) {
    if(i++ % 2) yield [prev, el];
    prev = el;
  }
}

function* shuffle(iterable) {
  const arr = [...iterable];
  while(arr.length)
     arr.splice(random(arr.length), 1)[0];
}

答案 2 :(得分:0)

这样的事情应该有效。其中大部分是从Fisher-Yates shuffle here

中复制而来的

&#13;
&#13;
function arrSlice(array) {
  var currentIndex = array.length, randomIndex, temporaryValue;
  var newArray = [], tempArray = [];

  while (currentIndex !== 0) {
    // Pick a remaining element...
    randomIndex = Math.floor(Math.random() * currentIndex);
    currentIndex -= 1;

    // And swap it with the current element.
    temporaryValue = array[currentIndex];
    array[currentIndex] = array[randomIndex];
    array[randomIndex] = temporaryValue;
    
    tempArray.push(array[currentIndex]);
    if (tempArray.length == 2) {
      newArray.push(tempArray);
      tempArray = [];
    }
  }
  return newArray;
}

console.log(arrSlice([1, 2, 3, 4, 5, 6]));
&#13;
&#13;
&#13;

答案 3 :(得分:0)

使用随机排序和减少链

&#13;
&#13;
var data = [1, 2, 3, 4, 5, 6, 7, 8];

var res = data.slice()
  .sort(_ => Math.random() - 0.5)
  .reduce((a, c, i, arr) => (i % 2 ? a : a.concat([arr.slice(i, i + 2)])), [])

console.log(JSON.stringify(res))
&#13;
&#13;
&#13;

答案 4 :(得分:0)

function arrSlice (arr) {
    return arr
    .sort(() => Math.random() > .5)  //shuffle
    .map((element,index) => index % 2 ? false : [arr[index], arr[index+1]])
    .filter(Boolean);
}
var arr = [1, 2, 3, 4, 5, 6, 7, 8];
console.log(arrSlice(arr));