Дублирование элементов массива с использованием функционального программирования - PullRequest
0 голосов
/ 11 ноября 2018

Я пытаюсь продублировать каждый элемент в массиве, но использую функциональный стиль.

У меня есть это в настоящее время:

["a", "b", "c"]

И я получаю это:

["a","a","b","b","c","c"]

До сих пор я пробовал следующее, отображая каждый элемент в массив, а затем используя flat (), чтобы получить 1d массив. Есть ли более чистый способ, потому что мне кажется, что я злоупотребляю картой и картой.

["a", "b", "c"].map(item => [item, item]).flat();

Есть ли лучший способ сделать это?


Я пытался привести пример как можно более простым, но не учел некоторые детали. Реальный ввод не отсортирован, потому что элементы не сопоставимы. Это что-то вроде:

[
  {
    a:"a"
    b:"b"
  },
  {
    c: 1
    d: 2
  },
  {
    apple: {},
    sellers: ["me", "her"]
  }
]

Дублированный результат должен быть примерно таким, где дублированные элементы находятся рядом друг с другом:

[
  {
    a:"a"
    b:"b"
  },
  {
    a:"a"
    b:"b"
  },
  {
    c: 1
    d: 2
  },
  {
    c: 1
    d: 2
  },
  {
    apple: {},
    sellers: ["me", "her"]
  },
  {
    apple: {},
    sellers: ["me", "her"]
  }
]

Ответы [ 4 ]

0 голосов
/ 11 ноября 2018

Я бы порекомендовал Array.prototype.flatMap

const twice = x =>
  [ x, x ]
  
console.log
  ( [ 'a', 'b', 'c' ] .flatMap (twice) // [ 'a', 'a', 'b', 'b', 'c', 'c' ]
  , [ 1, 2, 3, 4, 5 ] .flatMap (twice) // [ 1, 1, 2, 2, 3, 3, 4, 4, 5, 5 ]
  )

flatMap полезен для всех видов вещей

const tree =
  [ 0, [ 1 ], [ 2, [ 3 ], [ 4, [ 5 ] ] ] ]
  
const all = ([ value, ...children ]) =>
  [ value ] .concat (children .flatMap (all))
  
console.log (all (tree))
// [ 0, 1, 2, 3, 4, 5 ]

действительно классные вещи

const ranks =
  [ 'J', 'Q', 'K', 'A' ]
  
const suits =
  [ '♡', '♢', '♤', '♧' ]

console.log
  ( ranks .flatMap (r =>
      suits .flatMap (s =>
        [ [ r, s ] ]
      )
    )
  )

// [ ['J','♡'], ['J','♢'], ['J','♤'], ['J','♧']
// , ['Q','♡'], ['Q','♢'], ['Q','♤'], ['Q','♧']
// , ['K','♡'], ['K','♢'], ['K','♤'], ['K','♧']
// , ['A','♡'], ['A','♢'], ['A','♤'], ['A','♧']
// ]
0 голосов
/ 11 ноября 2018

Вы могли бы просто сделать это:

var arr = ["a", "b", "c"];
arr = arr.concat(arr).sort();

Это один из самых простых способов сделать то, что вы просите.

0 голосов
/ 11 ноября 2018

Array.reduce - это семантически подходящий метод: возьмите объект (в данном случае массив) и верните объект другого типа или другой длины или формы (примечание: отредактировано для использования Array.push для ускорения производительность за предложение @slider):

РЕДАКТИРОВАТЬ: я отредактировал свой ответ, чтобы отразить обновленные входные данные OP. Обратите внимание, что это решение является кросс-браузерным и совместимым с NodeJS без необходимости переноса.

let data = [
  {
    a:"a",
    b:"b",
  },
  {
    c: 1,
    d: 2
  },
  {
    apple: {},
    sellers: ["me", "her"]
  }
];

let result = data
  .reduce((acc, el) => {
    acc.push(el, el);
    return acc;
  }, []);
  
console.log(JSON.stringify(result, null, 2));

В противном случае вы можете map каждый элемент, продублировать его, а затем объединить их:

let data = [
  {
    a:"a",
    b:"b",
  },
  {
    c: 1,
    d: 2
  },
  {
    apple: {},
    sellers: ["me", "her"]
  }
];

let result = data.map(item => [item, item]).reduce((acc, arr) => acc.concat(arr));

console.log(JSON.stringify(result, null, 2));

Как упомянуто в других ответах здесь, любой из этих подходов имеет то преимущество, что не требует сортировки исходного массива.

0 голосов
/ 11 ноября 2018

Вы можете использовать функцию reduce и объединять один и тот же объект на каждой итерации.

let array = ["a", "b", "c"],
    result = array.reduce((a, c) => a.concat(c, c), []);
    
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...