Как сплести два массива в JavaScript? - PullRequest
0 голосов
/ 25 сентября 2018

Я очень запутался в том, чтобы заставить это работать, поскольку вложенные циклы все еще немного забавны для меня.

Со следующими двумя массивами:

let a = ['y','y','y'];
let z = ['x','x','x','x','x'];

Как мне получитьэто печатать одно значение из , а затем два значения из z после этого и так далее?

'y',
'x',
'x',
'y',
'x',
'x',
'y',
'x',
'x'

Если бы вместо этого были значения:

let a = ['y','y'];
let z = ['x','x','x','x','x'];

Это напечатало бы:

'y',
'x',
'x',
'y',
'x',
'x',
'x'

Это то, что я пробовал до сих пор:

for (let i = 0; i < a.length; i++) {
    console.log(a[i]);
    for (let j = 0; j < z.length; j++) {
      console.log(z[j], z[j+1]);
    // break?
    }
}

Ответы [ 11 ]

0 голосов
/ 25 сентября 2018

Вот пример использования Array.prototype.reduce () и присвоения деструктуры :

let a = ["y", "y", "y"];
let z = ["x", "x", "x", "x", "x"];

let y = a.reduce((acc, current, index) => {
  return [...acc, current, ...z.splice(0, a[index + 1] ? 2 : z.length)];
}, []);

console.log(y);
console.log(z);

На каждый элемент массива a вы берете ранее накопленный массив (первоначально []), добавьте элемент current и два элемента из z, если aимеет следующий элемент или остальные элементы z, если current является последним элементом a.К сожалению, это удаляет элементы из z в процессе, поэтому вы можете скопировать их перед запуском, то есть вы можете обернуть сокращение в функцию и передать копию z:

let a = ["y", "y", "y"];
let z = ["a", "b", "c", "d", "e", "f", "g"];

const interweave = (arr1, arr2) => {
  return arr1.reduce((acc, current, index) => {
    return [
      ...acc,
      current,
      ...arr2.splice(0, arr1[index + 1] ? 2 : arr2.length)
    ];
  }, []);
};

console.log(interweave(a, [...z]));
console.log(z);
0 голосов
/ 25 сентября 2018

Вы можете взять длину и вычислить интервал / часть длины массива для сращивания и передачи в набор результатов.

function getX(a, b) {
    var iA = Math.ceil(a.length / b.length),
        iB = Math.ceil(b.length / a.length),
        pA = 0,
        pB = 0,
        result = [];

    while (pA < a.length || pB < b.length) {
        result.push(
            ...a.slice(pA, pA += iA),
            ...b.slice(pB, pB += iB)
        );
    }
    return result;
}

console.log(getX(['y','y','y'], ['x','x','x','x','x']).join(' '));
console.log(getX(['y','y'], ['x','x','x','x','x']).join(' '));
0 голосов
/ 25 сентября 2018

Вам не нужен вложенный цикл вообще.Это можно сделать с помощью одного цикла с двумя счетчиками.

let a = ['y','y','y'];
let z = ['x','x','x','x','x'];
let result = [];

for(let i = 0, j = 0; i < a.length, j < z.length; i++, j+=2) {
	result.push(a[i], z[j], z[j+1]);
}

result = result.filter(item => item !== undefined);

console.log(result);

А вот тот же код, сжатый для однострочного ядра:

let a = ['y','y','y'];
let z = ['x','x','x','x','x'];
let result = [];

for(let i = 0, j = 0; i < a.length, j < z.length; i++, j+=2) {
	result.push.apply(result, [a[i], z[j], z[j+1]].filter(m => m !== undefined));
}

console.log(result);
0 голосов
/ 25 сентября 2018

Пожалуйста, ознакомьтесь с кодом ниже.Я поместил ваш ожидаемый результат в массив.

    let a = ['y','y'];
    let z = ['x', 'x', 'x', 'x', 'x'];
    let arr = [];
    for (let i = 0; i < a.length; i++) {
        var count = 0
      arr.push(a[i]);
      for (let j = i * 2; j < z.length; j++) {
        arr.push(z[j]);
        count++
        if (count > 1) {
            if (z[j+1] !== undefined && a[i+1] === undefined) {
            for (let k = j+1; k < z.length; k++) {
              arr.push(z[k])
            }
          }
        break;
        }
      }
    }
console.log(arr);
// ["y", "x", "x", "y", "x", "x", "x"]
0 голосов
/ 25 сентября 2018

Вы можете сделать это даже без for или while!попробуйте это:

let a = ['y','y','y'];
let z = ['x','x','x','x','x'];
console.log(
    [].concat.apply([], a.map(function(m, i){return [m].concat(z.slice(i*2, i*2+2));}))
);

Теперь вы можете присоединиться к результату, если хотите так:

let a = ['y','y','y'];
let z = ['x','x','x','x','x'];
console.log(
    [].concat.apply([], a.map(function(m, i){return [m].concat(z.slice(i*2, i*2+2));})).join(",")
);

Или, если вам нравится reduce функция, вы можете попробовать это:

let a = ['y','y','y'];
let z = ['x','x','x','x','x'];
console.log(
  a.reduce(function(ac, m, i){return ac.push.apply(ac, [m].concat(z.slice(i*2, i*2+2))), ac;}, [])
);
0 голосов
/ 25 сентября 2018
let c = j = 0;
z.map(function(item){
  if(c === 0 && a[j]){ console.log(a[j++]); }
  console.log(item);
  c = c > 0 ? 0 : c + 1;
});
0 голосов
/ 25 сентября 2018

Вот неразрушающий способ сделать это

var pointer = 0;

    for (let i = 0; i < a.length; i++) {
      var count = 0;
      console.log(a[i]);
      for (let j = pointer; j < z.length; j++) {    
        console.log(z[j]);
        count++;

        if(count == 2){
            count = 0;
            if(i == a.length-1) { continue; }else { pointer = j+1; break; }
        }

      }
    }
0 голосов
/ 25 сентября 2018
  let aIndex = 0, zIndex = 0;

 while(aIndex < a.length || zIndex < z.length) {
    console.log(
      a[aIndex++],
      z[zIndex++],
      z[zIndex++]
   );
 }
0 голосов
/ 25 сентября 2018

Один из вариантов - использовать петлю do / while.Используйте shift() для удаления первого элемента массива

let a = ['y1', 'y2', 'y3'];
let z = ['x1', 'x2', 'x3', 'x4', 'x5', 'x6'];

//Copy the array a and z
let aTemp = [...a]; 
let zTemp = [...z];

do {
  if (aTemp.length) console.log(aTemp.shift());
  if (zTemp.length) console.log(zTemp.shift());
  if (zTemp.length) console.log(zTemp.shift());
} while (aTemp.length || zTemp.length); //Loop while both the temp variables have elements
0 голосов
/ 25 сентября 2018

Я чиню твою петлю:

let a = ['y','y','y'];
let z = ['x','x','x','x','x'];
for (let i = 0; i < a.length; i++) {
  console.log(a[i]);
  console.log(z[i*2], z[i*2+1]);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...