Каков самый элегантный способ вставки объектов между элементами массива?

Я уверен, что есть много способов добиться этого, но я ищу что-то "элегантное".

a = [
  'a',
  'b',
  'c'
];

magicArrayJoin(a, {value: 255} ); // insert the same object between each item

result ==  [
  'a',
  {value: 255},
  'b',
  {value: 255}
  'c'
];

Все предложения приветствуются.:)

Ответ 1

У Рамды есть метод вкрапления, который:

Создает новый список с разделителем, вставленным между элементами.

Код:

R.intersperse({name: 'separator'}, ['one', 'two', 'three']);

Результат:

[
    'one',
    {name: 'separator'},
    'two',
    {name: 'separator'},
    'three'
]

Ответ 2

Вы можете сделать это с flatMap. Это может быть найдено из lodash например

_.flatMap([1,2,3,4], (value, index, array) =>
     array.length -1 !== index // check for the last item
     ? [value, "s"]
     : value
);

Выходы

[1, "s", 2, "s", 3, "s", 4]

Обновить

Предложение Array # flatMap находится в разработке, поэтому в будущем это должно сработать:

[1, 2, 3, 4].flatMap(
    (value, index, array) =>
        array.length - 1 !== index // check for the last item
            ? [value, "s"]
            : value,
);

Ответ 3

На мой взгляд, самый элегантный способ сделать это следующий:

Версия синтаксиса ES6

const insertIntoArray = (arr, value) => {

    return arr.reduce((result, element, index, array) => {

        result.push(element);

        if (index < array.length - 1) {
            result.push(value);
        }

        return result;
    }, []);
};

Использование:

insertIntoArray([1, 2, 3], 'x'); // => [1, 'x', 2, 'x', 3]

Ответ 4

Обычный цикл кажется лучшим:

function intersperse(arr, el) {
    var res = [], i=0;
    if (i < arr.length)
        res.push(arr[i++]);
    while (i < arr.length)
        res.push(el, arr[i++]);
    return res;
}

Если вы ищете что-то элегантное, вероятно, придется использовать какой-то concatMap, как в

function concatMap(arr, fn) { return [].concat.apply([], arr.map(fn)); }
function intersperse(arr, el) { return concatMap(arr, x => [el, x]).slice(1); }

Ответ 5

Неизменяемый раствор

При уменьшении массива функция уменьшения не должна мутировать массив, а возвращает новое значение (в данном случае новый массив). Таким образом, изменения будут применяться только к возвращенному массиву, а не к исходному, и побочные эффекты будут устранены.

const insertBetween = (insertee, array) => array.reduce(
    (acc, item, i, { length }) => {
        if (i && i < length) {
            return [...acc, insertee, item];
        }
        return [...acc, item];
    },
    []
);

Ответ 6

Вы можете добиться этого, используя сокращение (оно также неизменно).

const insertBetween = (insertion, array) =>
    array.reduce(
        (newArray, member, i, array) =>
            i < array.length - 1 
                ? newArray.concat(member, insertion) 
                : newArray.concat(member),
        []
    );

const result = insertBetween('and', [1, 2, 3]);

console.log(result);

// outputs;
// [
//   1, 
//   'and', 
//   2, 
//   'and', 
//   3
// ]

Ответ 7

function insertObject(arr, obj) {
  var result = [];

  function insert(element, index) {
    result.push(element);
    if (index + 1 < arr.length) {
      result.push(obj);
    }
  }
  arr.forEach(insert);
  return result;
}
var a = [1, 2, 3, 4];
insertObject(a, {
  test: 'test'
});

Ответ 8

Используя сплайсинг, как предлагает Kamen, вы можете сделать что-то вроде:

const numSeparators = arr.length - 1;
for (let i = 1; i <= numSeparators; i++) {
    const index = (i * 2) - 1;
    arr.splice(index, 0, { value: 255 });
}

Ответ 9

для простого чисто функционального способа я предлагаю сделать это следующим образом:

const magicArrayJoin = (array, el) =>
  array.length ?
    array.slice(1).reduce((acc, cur) => acc.concat([el, cur]), [array[0]]) :
    []

p.n. этот способ не самый результативный в javascript

Ответ 10

Однострочник с использованием простого ES6:

const interleave = (arr, thing) => [].concat(...arr.map(n => [n, thing])).slice(0, -1)

Использование:

interleave(['foo', 'bar', 'baz'], 'avocado')

Печать:

> ["foo", "avocado", "bar", "avocado", "baz"]

Ответ 11

ES6:

const arrayWithSeparator = array.reduce((a, i) => a.length ? a.push(separator) && a.push(i) && a : a.push(u) && a, [])

Ответ 12

Array.splice() должен выполнить следующее задание:

a.splice(1, 0, {value : 255})

Первый аргумент - это позиция, в которой вы хотите удалить или вставить элементы, вторая - счет удаления, третий (необязательный) - это новый элемент [s], который вы хотите вставить.