Функциональный способ вставить значение между всеми элементами в массиве - PullRequest
0 голосов
/ 15 января 2019

Допустим, у меня есть следующий массив:

const myArray = ["q", "w", "e", "r", "t", "y"]

Я хотел бы добавить элемент между всеми элементами, например:

myArray.someMethod("XXX")
// ["q", "XXX", "w", "XXX", "e", "XXX", "r", "XXX", "t", "XXX", "y"]

В некотором смысле, это то, что делает .join, но я бы хотел, чтобы вывод был другим массивом, а не строкой.

Я знаю, как сделать это с помощью цикла, но я хотел бы знать, что это «функциональный» способ достичь этого.

Ответы [ 6 ]

0 голосов
/ 15 января 2019

Вы можете использовать reduce для преобразования исходного массива и либо поместить его в функцию с двумя аргументами, либо добавить его в качестве метода Array.prototype (если вы действительно хотите вызвать метод в посте):

const myArray = ["q", "w", "e", "r", "t", "y"]

// A function taking array and glue arguments

const interpose = (array, glue) => array.reduce(
   (acc, c,i,a) => (
        acc.push(c) && (i < a.length -1) && acc.push( glue),
        acc
    ), []
);

// As an array method

Array.prototype.interpose = function( glue) {
    return  this.reduce(
    (acc, c,i,a) => (
         acc.push(c) && (i < a.length -1) && acc.push( glue),
         acc
     ), []);
}

// Test

console.log( 'interpose( myArray, "XXX" = %s', interpose( myArray, "XXX"));
console.log( 'myArray.interpose("XXX")  = %s', myArray.interpose("XXX"));
0 голосов
/ 15 января 2019

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

const
    zip = ([a, ...r], v) => r.length ? [a, v, ...zip(r, v)] : [a];

console.log(zip(["q", "w", "e", "r", "t", "y"], 'XXX'));
.as-console-wrapper { max-height: 100% !important; top: 0; }
0 голосов
/ 15 января 2019

В функциональном программировании Array - это Monad , что означает, что он плоский. FlatMap - это реализация оператора связывания Monadic, который для массива отображает элемент в новый массив и объединяет их вместе.

С этой идеей вам просто нужно добавить новое значение в выходной массив внутри функции flatMap. Смотрите следующее

Array.prototype.someMethod = function(a){ return this.flatMap(i => [i,a]) }

myArray.someMethod("XXX")
// Array(12) [ "q", "XXX", "w", "XXX", "e", "XXX", "r", "XXX", "t", "XXX", … ]

Приведенный выше пример добавляет XXX в конец массива, поэтому мы можем игнорировать заполнение последнего элемента, используя аргумент index в flatMap следующим образом

Array.prototype.someMethod = function(a){ let L=this.length; return this.flatMap((n,i) => (i<L-1) ? [n,a] : [n]) }

myArray.someMethod("XXX")
// Array(11) [ "q", "XXX", "w", "XXX", "e", "XXX", "r", "XXX", "t", "XXX", "y"]
0 голосов
/ 15 января 2019

Вы можете использовать карту () с плоским ()

const myArray = ["q", "w", "e", "r", "t", "y"];
const newArray = myArray.map((i) => {
   return [i, 'xxx']
}).flat();

console.log(newArray);
0 голосов
/ 15 января 2019

Вы можете использовать .map() с .concat():

const data = ["q", "w", "e", "r", "t", "y"];
const str = "XXX";

const insertValue = (arr, val) => [].concat(
    ...arr.map((v, i) => (i > 0 ? [str, v] : v))
);

console.log(insertValue(data, str));
.as-console-wrapper { max-height: 100% !important; top: 0; }
0 голосов
/ 15 января 2019

const myArray = ["q", "w", "e", "r", "t", "y"]
const joinStr = 'xxx';
console.log(myArray.join(','+ joinStr + ',').split(','));
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...