декартово произведение списков

мне понадобится декартово произведение двух списков javascript.

Пример:

let l1 = ['a','e','f'];
let l2 = ['1','3','2'];
let lp = prod(l1, l2);

лп будет

[
['a','1'],
['e','1'],
['f','1'],
['a','3'],
['e','3'],
['f','3'],
['a','2'],
['e','2'],
['f','2']
]

Я могу легко сделать это с помощью циклов for/foreach, но интересно, есть ли у кого-нибудь элегантные предложения с функциями карты.


person spacm    schedule 30.01.2020    source источник


Ответы (4)


Вы можете использовать комбинацию сокращения и карты:

console.log(l1.reduce((result, el1) => {
  result.push(...l2.map((el2) => [el1, el2]));
  return result;
}, []));
person Kaca992    schedule 30.01.2020

Попробуйте следующее

let l1 = ['a','e','f'];
let l2 = ['1','3','2'];

console.log(l1.map(a => {
  return l2.map(b => {
    return [a,b];
  })
}).flat())

person Ratul Sharker    schedule 30.01.2020
comment
Выглядит правильно и элегантно, но я получаю плоскую ошибку, а не функцию. Безопасно ли использовать flat()? - person spacm; 30.01.2020
comment
Согласно MDN flat недоступен в Edge & Internet Explorer. developer.mozilla.org/en-US/ документы/Интернет/JavaScript/Справочник/ - person Ratul Sharker; 30.01.2020
comment
Хорошо, я бы избегал этого, даже если это не мои любимые браузеры. Но спасибо за ответ, это действительно элегантно. - person spacm; 30.01.2020

Это должно работать:

function prod(l1, l2) {
  return l2.reduce(
    (p, b) => p.concat(l1.map(a => [a, b])),
    [],
  );
}

const l1 = ['a','e','f'];
const l2 = ['1','3','2'];
const lp = prod(l1, l2);

console.log(lp);

person technophyle    schedule 30.01.2020

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

let l1 = ['a','e','f'],
    l2 = ['1','3','2'],
    result = [l1, l2]
        .reduce((a, b) => a.reduce((r, v) => r.concat(b.map(w => [].concat(v, w))), []));

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

person Nina Scholz    schedule 30.01.2020