iteratorUtils.js

/**
 * Set of utils for working with iterators in SFCC.
 * @module iteratorUtils
 */

const SeekableIterator = require('dw/util/SeekableIterator');

/**
 * Iterates over each item in the iterator and calls the provided callback function.
 * 
 * @param {dw.util.Iterator} iterator - The iterator to iterate over.
 * @param {function} callback - The callback function to be called for each item.
 * Takes two arguments: the current item and its index.
 * @returns {void}
 */
function forEach(iterator, callback) {
  for (let index = 0; iterator.hasNext(); index++) {
    let currentItem = iterator.next();
    callback(currentItem, index);
  }

  if (iterator instanceof SeekableIterator) {
    iterator.close();
  }
}

/**
 * Maps each item in the iterator using the provided callback function.
 * 
 * @param {dw.util.Iterator} iterator - The iterator to iterate over.
 * @param {function} callback - The callback function to map each item.
 * Takes two arguments: the current item and its index.
 * @returns {array} A new array containing the mapped items.
 */
function map(iterator, callback) {
  let resultArray = [];

  forEach(iterator, (currentItem, index) => {
    let mappedItem = callback(currentItem, index);
    resultArray.push(mappedItem);
  });

  return resultArray;
}

/**
 * Filters items in the iterator based on the provided callback function.
 * 
 * @param {dw.util.Iterator} iterator - The iterator to iterate over.
 * @param {function} callback - The callback function to filter items.
 * Takes two arguments: the current item and its index.
 * @returns {array} An array containing the filtered items.
 */
function filter(iterator, callback) {
  let filteredArray = [];

  forEach(iterator, (currentItem, index) => {
    if (callback(currentItem, index)) {
      filteredArray.push(currentItem);
    }
  });

  return filteredArray;
}

/**
 * Reduces the items in the iterator to a single value using the provided callback function.
 * 
 * @param {dw.util.Iterator} iterator - The iterator to iterate over.
 * @param {function} callback - The callback function to reduce items.
 * Takes three arguments: the accumulator, the current item, and its index.
 * @param {*} initialValue - The initial value of the accumulator.
 * @returns {*} The final value of the accumulator after iteration.
 */
function reduce(iterator, callback, initialValue) {
  let accumulator = initialValue;

  forEach(iterator, (currentItem, index) => {
    if (accumulator === undefined && index === 0) {
      accumulator = currentItem;
    } else {
      accumulator = callback(accumulator, currentItem, index);
    }
  });

  return accumulator;
}

module.exports = {
  forEach,
  map,
  filter,
  reduce
};