Слияние (архивирование) двух массивов разной длины с map () в JavaScript - PullRequest
0 голосов
/ 22 сентября 2019

Я пытаюсь обернуть голову вокруг метода map (), в этом случае я использую его для объединения (zip) двух массивов разной длины.Я проверил предыдущие вопросы, касающиеся архивирования в JavaScript, но они в основном касались массивов одинаковой длины.

У меня есть два массива:

const countries = ['US', 'FR', 'IT']
const area = [100, 105, 110, 115, 120, 125, 130]

let merge = countries.map(function (c) {
    area.map(function (a) {
        return c + a
    // This returns an array of length 3 (prints country + all areas into one array position)
    // However if I create a third array and use push(c + a) here instead then length is 21 (which is what I am trying to achieve). 
    })
})

Я возвращаю неправильные значения?Как я написал в комментарии, если я печатаю или помещаю (c + a) в другой массив, я получаю все 21 возможных комбинаций.Весь смысл map () в получении нового массива, поэтому я бы предпочел не вставлять третий.Я также слышал, что вложенные циклы forEach - это плохая практика (если я так или иначе должен был пойти на это).

Ответы [ 3 ]

3 голосов
/ 22 сентября 2019

.map обязательно создаст новый массив такой же длины, что и итеративный массив.Поскольку countries имеет 3 элемента, ваш вывод также будет иметь 3 элемента (массив массивов), если вы используете countries.map.

Использование .map не будет работать здесь, потому что ни один из ваших входных массивовимеют ту же длину, что и желаемый выходной массив.Либо .push для внешней переменной, о которой вы уже знаете, либо используйте .reduce и нажмите на аккумулятор:

const countries = ['US', 'FR', 'IT']
const area = [100, 105, 110, 115, 120, 125, 130]

const merged = countries.reduce((merged, c) => {
  area.forEach((a) => {
    merged.push(c + a);
  });
  return merged;
}, []);
console.log(merged);

Алгоритм создания массива длиной 21 из массивов длиной 7 и 3 обязательно будет включать в себя вложенный цикл - в этом нет ничего плохого.

1 голос
/ 22 сентября 2019

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

const countries = ['US', 'FR', 'IT']
const area = [100, 105, 110, 115, 120, 125, 130]

let merge = countries.map(function (c) {
    return area.map(function (a) {
        return c + a
    })
}).flat()

console.log(merge)

Еще один способ - использовать flatMap

const countries = ['US', 'FR', 'IT']
const area = [100, 105, 110, 115, 120, 125, 130]

let merge = countries.flatMap((c, i) => area.map(a => c + a))

console.log(merge)
0 голосов
/ 22 сентября 2019

Я думаю, вы хотите что-то более похожее на это:

const countries = ['US', 'FR', 'IT'];
const area = [100, 105, 110, 115, 120, 125, 130];
let merge = countries.map(x => [x, area]);
console.log(merge);

, и вы должны получить

Array [Array ["US", Array [100, 105, 110, 115, 120, 125, 130]], Array ["FR", Array [100, 105, 110, 115, 120, 125, 130]], Array ["IT", Array [100, 105, 110, 115, 120, 125, 130]]]
...