Javascript эквивалент функции zip в Python - PullRequest
180 голосов
/ 01 февраля 2011

Существует ли javascript-эквивалент функции zip в Python? То есть, учитывая, что несколько массивов одинаковой длины создают массив пар.

Например, если у меня есть три массива, которые выглядят так:

var array1 = [1, 2, 3];
var array2 = ['a','b','c'];
var array3 = [4, 5, 6];

Выходной массив должен быть:

var output array:[[1,'a',4], [2,'b',5], [3,'c',6]]

Ответы [ 16 ]

2 голосов
/ 19 октября 2018

Вы можете уменьшить массив массивов и отобразить новый массив, взяв результат индекса внутреннего массива.

var array1 = [1, 2, 3],
    array2 = ['a','b','c'],
    array3 = [4, 5, 6],
    array = [array1, array2, array3],
    transposed = array.reduce((r, a) => a.map((v, i) => (r[i] || []).concat(v)), []);

console.log(transposed);
1 голос
/ 28 февраля 2018

Вариант решения для ленивого генератора :

function* iter(it) {
    yield* it;
}

function* zip(...its) {
    its = its.map(iter);
    while (true) {
        let rs = its.map(it => it.next());
        if (rs.some(r => r.done))
            return;
        yield rs.map(r => r.value);
    }
}

for (let r of zip([1,2,3], [4,5,6,7], [8,9,0,11,22]))
    console.log(r.join())

// the only change for "longest" is some -> every

function* zipLongest(...its) {
    its = its.map(iter);
    while (true) {
        let rs = its.map(it => it.next());
        if (rs.every(r => r.done))
            return;
        yield rs.map(r => r.value);
    }
}

for (let r of zipLongest([1,2,3], [4,5,6,7], [8,9,0,11,22]))
    console.log(r.join())

И это классическая идиома питона "n-group" zip(*[iter(a)]*n):

triples = [...zip(...Array(3).fill(iter(a)))]
0 голосов
/ 25 апреля 2018

Если вы в порядке с ES6:

const zip = (arr,...arrs) =>(
                            arr.map(
                              (v,i) => arrs.reduce((a,arr)=>[...a, arr[i]], [v])))
0 голосов
/ 21 февраля 2018

Это сбивает строку с Ddi ответа на основе итератора:

function* zip(...toZip) {
  const iterators = toZip.map((arg) => arg[Symbol.iterator]());
  const next = () => toZip = iterators.map((iter) => iter.next());
  while (next().every((item) => !item.done)) {
    yield toZip.map((item) => item.value);
  }
}
0 голосов
/ 01 февраля 2011

Я пробежался по этому вопросу в чистом JS, удивляясь, как плагины, размещенные выше, сделали свою работу.Вот мой результат.Я предвосхищу это, говоря, что я понятия не имею, насколько стабильно это будет в IE и т.п.Это просто быстрый макет.

init();

function init() {
    var one = [0, 1, 2, 3];
    var two = [4, 5, 6, 7];
    var three = [8, 9, 10, 11, 12];
    var four = zip(one, two, one);
    //returns array
    //four = zip(one, two, three);
    //returns false since three.length !== two.length
    console.log(four);
}

function zip() {
    for (var i = 0; i < arguments.length; i++) {
        if (!arguments[i].length || !arguments.toString()) {
            return false;
        }
        if (i >= 1) {
            if (arguments[i].length !== arguments[i - 1].length) {
                return false;
            }
        }
    }
    var zipped = [];
    for (var j = 0; j < arguments[0].length; j++) {
        var toBeZipped = [];
        for (var k = 0; k < arguments.length; k++) {
            toBeZipped.push(arguments[k][j]);
        }
        zipped.push(toBeZipped);
    }
    return zipped;
}

Это не пуленепробиваемый, но все же интересно.

0 голосов
/ 01 февраля 2011

Библиотека Mochikit предоставляет эту и многие другие функции, подобные Python. Разработчик Mochikit также является фанатом Python, поэтому он имеет общий стиль Python, а также обертывает асинхронные вызовы в скрученной среде.

...