Iterate an array as a pair (current, next) in JavaScript

In the question “ Iterating a List as a Pair (Current, Next)” in Python, OP is interested in iterating a list of Python as a series of current, nextpairs. I have the same problem, but I would like to do this in JavaScript in the cleanest way, possibly using lodash .

This is easy to do with a simple loop for, but it is not very elegant.

for (var i = 0; i < arr.length - 1; i++) {
  var currentElement = arr[i];
  var nextElement = arr[i + 1];
}

Lodash can almost do this:

_.forEach(_.zip(arr, _.rest(arr)), function(tuple) {
  var currentElement = tuple[0];
  var nextElement = tuple[1];
})

The subtle problem with this is that it nextElementwill be at the last iteration undefined.

Of course, the ideal solution would be to simply have pairwisea lodash function that only looped as needed.

_.pairwise(arr, function(current, next) {
  // do stuff 
});

- , ? JavaScript, ?


: arr = [1, 2, 3, 4], pairwise : [1, 2], [2, 3], [3, 4], [1, 2], [3, 4]. , Python.

+11
13

, , "" , :

arr = [1, 2, 3, 4];

function pairwise(arr, func){
    for(var i=0; i < arr.length - 1; i++){
        func(arr[i], arr[i + 1])
    }
}

pairwise(arr, function(current, next){
    console.log(current, next)
})

, i, + n, :

function pairwise(arr, func, skips){
    skips = skips || 1;
    for(var i=0; i < arr.length - skips; i++){
        func(arr[i], arr[i + skips])
    }
}

pairwise([1, 2, 3, 4, 5, 6, 7], function(current,next){
    console.log(current, next) // displays (1, 3), (2, 4), (3, 5) , (4, 6), (5, 7)
}, 2)
+7

Ruby each_cons:

(1..5).each_cons(2).to_a # => [[1, 2], [2, 3], [3, 4], [4, 5]]

, ; , " " npm:

const eachCons = require('each-cons')

eachCons([1, 2, 3, 4, 5], 2) // [[1, 2], [2, 3], [3, 4], [4, 5]]

aperture Ramda, :

const R = require('ramda')

R.aperture(2, [1, 2, 3, 4, 5]) // [[1, 2], [2, 3], [3, 4], [4, 5]]
+6

, , Haskell: fooobar.com/questions/575816/...

Lodash, :

const zipAdjacent = function<T> (ts: T[]): [T, T][] {
  return zip(dropRight(ts, 1), tail(ts));
};
zipAdjacent([1,2,3,4]); // => [[1,2], [2,3], [3,4]]

( Haskell, dropRight, Lodash zip - Haskell's`: .)

:

const zipAdjacent = function<T> (ts: T[]): [T, T][] {
  return R.zip(ts, R.tail(ts));
};
zipAdjacent([1,2,3,4]); // => [[1,2], [2,3], [3,4]]

Ramda , aperture. , , , , 2:

R.aperture(2, [1,2,3,4]); // => [[1,2], [2,3], [3,4]]
R.aperture(3, [1,2,3,4]); // => [[1,2,3],[2,3,4]]
+3

Array.reduce . // .

, .

function pairwiseEach(arr, callback) {
  arr.reduce((prev, current) => {
    callback(prev, current)
    return current
  })
}

function pairwise(arr, callback) {
  const result = []
  arr.reduce((prev, current) => {
    result.push(callback(prev, current))
    return current
  })
  return result
}

const arr = [1, 2, 3, 4]
pairwiseEach(arr, (a, b) => console.log(a, b))
const result = pairwise(arr, (a, b) => [a, b])

const output = document.createElement('pre')
output.textContent = JSON.stringify(result)
document.body.appendChild(output)
Hide result
+2

:

[1,2,3,4].reduce((acc, v, i, a) => { if (i < a.length - 1) { acc.push([a[i], a[i+1]]) } return acc; }, []).forEach(pair => console.log(pair[0], pair[1]))

:

[1, 2, 3, 4].
reduce((acc, v, i, a) => {
  if (i < a.length - 1) {
    acc.push([a[i], a[i + 1]]);
  }
  return acc;
}, []).
forEach(pair => console.log(pair[0], pair[1]));

:

1 2
2 3
3 4
+2

- :

const nWise = (n, array) => {
  iterators = Array(n).fill()
    .map(() => array[Symbol.iterator]());
  iterators
    .forEach((it, index) => Array(index).fill()
      .forEach(() => it.next()));
  return Array(array.length - n + 1).fill()
    .map(() => (iterators
      .map(it => it.next().value);
};

const pairWise = (array) => nWise(2, array);

, , , , :

const sizedArray = (n) => Array(n).fill();

sizedArray forEach times , . :

const times = (n, cb) => {
  while (0 < n--) {
    cb();
  }
}

, .

, Array.fill , . , Array(n).fill(array[Symbol.iterator]()) . :

const fillWithCb = (n, cb) => sizedArray(n).map(cb);

:

const nWise = (n, array) => {
  iterators = fillWithCb(n, () => array[Symbol.iterator]());
  iterators.forEach((it, index) => times(index, () => it.next()));
  return fillWithCb(
    array.length - n + 1,
    () => (iterators.map(it => it.next().value),
  );
};

currying, :

const nWise = n => array => {
  iterators = fillWithCb(n, () => array[Symbol.iterator]());
  iterators.forEach((it, index) => times(index, () => it.next()));
  return fillWithCb(
    array.length - n + 1,
    () => iterators.map(it => it.next().value),
  );
};

const pairWise = nWise(2);

, :

> pairWise([1, 2, 3, 4, 5]);
// [ [ 1, 2 ], [ 2, 3 ], [ 3, 4 ], [ 4, 5 ] ]
+2

, Array.prototype.shift:

Array.prototype.pairwise = function (callback) {
    const copy = [].concat(this);
    let next, current;

    while (copy.length) {
        current = next ? next : copy.shift();
        next = copy.shift();
        callback(current, next);
    }
};

:

// output:
1 2
2 3
3 4
4 5
5 6

[1, 2, 3, 4, 5, 6].pairwise(function (current, next) {
    console.log(current, next);
});

, :

while (this.length) {

Array.prototype.shift , , , , , 0. "" JavaScript, .

current = next ? next : this.shift();

next , current. , .

.

+1

d3.js , sliding:

console.log(d3.pairs([1, 2, 3, 4])); // [[1, 2], [2, 3], [3, 4]]
<script src="http://d3js.org/d3.v5.min.js"></script>
Hide result

# d3.pairs(array [, reducer]) <>

, - 1. , , .

+1

:

function * pairwise (iterable) {
    const iterator = iterable[Symbol.iterator]()
    let current = iterator.next()
    let next = iterator.next()
    while (!current.done) {
        yield [current.value, next.value]
        current = next
        next = iterator.next()
    }
}

console.log(...pairwise([]))
console.log(...pairwise(['apple']))
console.log(...pairwise(['apple', 'orange', 'kiwi', 'banana']))
console.log(...pairwise(new Set(['apple', 'orange', 'kiwi', 'banana'])))
Hide result

:

  • , (, ).
  • .
  • , .
+1

. , .

function* generate_windows(array, window_size) {
    const max_base_index = array.length - window_size;
    for(let base_index = 0; base_index <= max_base_index; ++base_index) {
        yield array.slice(base_index, base_index + window_size);
    }
}
const windows = generate_windows([1, 2, 3, 4, 5, 6, 7, 8, 9], 3);
for(const window of windows) {
    console.log(window);
}
0

forEach :

yourArray.forEach((current, idx, self) => {
  if (let next = self[idx + 1]) {
    //your code here
  }
})
0

Lodash , : https://lodash.com/docs#chunk

_.chunk(array, 2).forEach(function(pair) {
  var first = pair[0];
  var next = pair[1];
  console.log(first, next)
})
-1

, - :

Array.prototype.pairEach = function(callback){
   for(var i=0, l= this.length-1;i<l;i++){
     callback(this[i], this[i+1]);
   }
}

//call as follows
var a = [1,2,3,4];
a.pairEach(callback);
-1

Source: https://habr.com/ru/post/1677859/


All Articles