2016-06-14 7 views
0

Учитывая массив, [1, 2, 3, 4, 5], что является наиболее эффективным методом для объединения каждого из элементов последовательно, например: [[1,2], [2,3], [3,4], [4,5]]?Последовательное сопряжение элементов в массиве

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

ответ

4

Используйте простой for loop

var data = [1, 2, 3, 4, 5]; 
 
var res = []; 
 

 
for (var i = 0; i < data.length-1; i++) { 
 
res.push(data.slice(i, i+2)); 
 
} 
 

 
console.log(res);

С Array#reduce методом

console.log(
 
    [1, 2, 3, 4, 5].reduce(function(a, b, i) { 
 
    if (i == 1) return [[a, b]]; 
 
    a.push([a[a.length - 1][1], b]); 
 
    return a 
 
    }) 
 
)

С Array#reduce метод с начальным значением, как пустой массив

console.log(
 
    [1, 2, 3, 4, 5].reduce(function(a, b, i, arr) { 
 
    arr[i + 1] !== undefined && a.push([b, arr[i + 1]]) 
 
    return a 
 
    }, []) 
 
)

+0

Можете ли вы объяснить, что делает эта линия? 'arr [i + 1] && a.push ([b, arr [i + 1]])' Он работает, я не понимаю, что делает оператор &&. –

+1

@SpencerAllenGardner, если 'arr [i + 1]' является правдивым значением, тогда операция push будет выполняться ... это просто, чтобы избежать 'undefined' ... Это сокращенное выражение для' if (arr [i + 1]) a. push ([b, arr [i + 1]]) ' –

-3

Сокращение - это самый элегантный способ сделать это.

[1,2,3,4,5].reduce((a,b,c) => { 
    a.push([c,b]); 
    return a; 
}, []) 
+2

Это не правильно. Вы используете индекс 'c' вместо смежного элемента массива. –

+2

Это не дает результат, который ищет OP. –

1

Чтобы ответить на "элегантную" немного ...;)

let pairwise = function *(it) { 
 
    var 
 
     a = it[Symbol.iterator](), 
 
     b = it[Symbol.iterator](); 
 

 
    b.next(); 
 

 
    for (var x of b) { 
 
     yield [a.next().value, x] 
 
    } 
 
}; 
 

 
console.log(Array.from(pairwise([1,2,3,4,5])))

0

Еще один короткий с использованием Array.forEach и Array.push функции:

var arr = [1, 2, 3, 4, 5], pairs = []; 
arr.forEach((v, k, arr) => arr[k+1] && pairs.push([v, arr[k+1]])); 

console.log(JSON.stringify(pairs)); // [[1,2],[2,3],[3,4],[4,5]] 
1

Использование lodash для данного array:

var result = _.chunk(_.sortBy(array.concat(_.slice(array, 1, array.length - 1))), 2); 

Проверить jsfiddle

Так что если array = [1,2,3,4,5] мы имеем шаги:

_.slice(array, 1, array.length - 1)    

     // = [2,3,4] 

array.concat(_.slice(array, 1, array.length - 1) 

     // = [1,2,3,4,5].concat([2,3,4]) = [1,2,3,4,5,2,3,4] 

_.sortBy(array.concat(_.slice(array, 1, array.length - 1)) 

     // _sortBy([1,2,3,4,5,2,3,4]) = [1,2,2,3,3,4,4,5] 

_.chunk(_.sortBy(array.concat(_.slice(array, 1, array.length - 1))), 2) 

     // _chunk([1,2,2,3,3,4,4,5],2) = [[1,2],[2,3],[3,4],[4,5]] 
0

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

const res = [1, 2, 3, 4, 5].reduce(
 
     ([b, acc], a) => [a, acc.concat([[b, a]])] 
 
    , [null, []])[1].slice(1) 
 

 
    console.log(res)

Семя reduce является кортеж из двух элементов: [null, []]. null представляет собой текущий элемент массива, а результат [].

В первой итерации reduce:

([b, acc], a) => ...b = null и acc = []

Функция создает новый кортеж, первый элемент в кортеже является текущим элементом массива и второго элемента является результатом ,Во второй итерации:

([b, acc], a) => ..., b = 1 и acc = [[null, 1]]

второй итерации добавит (CONCAT) [1, 2] к результату (АСС).

В третьей итерации:

([b, acc], a) => ..., b = 2 и acc = [[null, 1], [1, 2]]

И так далее, так далее:

const trace = (x, y) => { 
 
    console.log(x); 
 
    return y; 
 
} 
 

 
const json = x => JSON.stringify(x) 
 

 
const res = [1, 2, 3, 4, 5].reduce(
 
    ([b, acc], a) => trace(
 
     `a = ${a}, b = ${b} acc = ${json(acc)} ++ ${json([[b, a]])}` 
 
    , [a, acc.concat([[b, a]])] 
 
) 
 
    , [null, []]) // seed 
 
    // the result is a tuple `[currentElement, finalResult], we extract finalResult here 
 
    [1] 
 
    // -1 element of the original array was null (check the seed), let's remove it from the result 
 
    .slice(1) 
 

 
console.log(res)

Мы можем думать об этой проблеме еще один способ: мы как бы присоединяемся к элементам того же массива друг с другом в кортежи. Использование Ramdazip функции элегантна, но имеет компромисс производительности, потому что мы идем через список дважды:

const arr = [1, 2, 3, 4, 5] 
 
const res = R.zip(arr, R.drop(1, arr)) 
 
console.log(res)
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.21.0/ramda.min.js"></script>

Смежные вопросы