【问题标题】:*Chainable* Javascript method to do something for each item of an array*Chainable* Javascript 方法为数组的每个项目做一些事情
【发布时间】:2021-05-03 19:27:22
【问题描述】:

我正在寻找一种语义方式来对 Javascript 数组中的每个项目执行一些步骤,同时 在方法链的中间,因为 I can't use forEach 出于任何原因:

forEach() 对每个数组元素执行一次回调函数;与 map() 或 reduce() 不同,它总是返回值 undefined 并且不可链接。典型的用例是在链的末端执行副作用。

Laravel 集合具有 eachtap,它们的功能大致相同。

我想我可以只使用map 并在最后返回原始项目,但我想知道是否有更内置的语义方法可以这样做。

【问题讨论】:

  • 你到底想做什么?
  • 地图不返回原始项目。您能否详细说明您想要实现的目标?也许样本输入和输出会有所帮助。
  • 请举例说明您应该通过该函数运行的数据

标签: javascript arrays foreach each method-chaining


【解决方案1】:

虽然这个解决方案远非完美,但您可以简单地过滤数组并在每个元素上返回 true。

这将允许您保留对数组中每个元素的引用并为每个元素执行一个操作。

array.someChainableFunction().filter(item => {
    // we do something with each item
    // then return true to keep all the items.
    return true;
}).someOtherChainableFunction()...

const elements = [
  {
    value: 1
  },
  {
    value: 2
  },
  {
    value: 3
  },
  {
    value: 4
  },
  {
    value: 5
  },
];

const output = elements.map(item => {
  item.value++;
  return item;
}).filter(item => {
  // we do something with each items.
  console.log('first map', item);
  // and we return true since we don't want to actually filter the array.
  return true;
}).map(item => {
  item.value++;
  return item;
}).forEach(item => {
  console.log('second map', item);
});

console.log(output);

我强烈建议将它包装在另一个函数中,这样更容易理解,并且在您的代码中使用它时不会混淆其他开发人员。

Array.prototype.tap = function (callable) {
      return this.filter(item => {
        callable(item);
        return true;
      });
    }

array.someChainableFunction().tap(item => {
    // we do something with each item
}).someOtherChainableFunction()...

// here, we use an anonymous function rather than an arrow function
// because we need to have access to the `this` context of the Array object.
Array.prototype.tap = function (callable) {
  return this.filter(item => {
    callable(item);
    return true;
  });
}

const elements = [
  {
    value: 1
  },
  {
    value: 2
  },
  {
    value: 3
  },
  {
    value: 4
  },
  {
    value: 5
  },
];

const output = elements.map(item => {
  item.value++;
  return item;
}).tap(item => {
  // we use our custom function.
   console.log('first map', item);
}).map(item => {
  item.value++;
  return item;
}).tap(item => {
  console.log('second map', item);
});

console.log(output);

【讨论】:

  • 这是一种方法。类似于使用map并在最后返回原始项目。
【解决方案2】:

我想我可以只使用 map 并在最后返回原始项目,但我想知道是否有更内置的语义方法可以这样做。

一个与map 一样的内置方法,除了它返回数组不变而不你的代码返回每个元素?

或者像forEach这样的内置方法,只是它返回的数组不变?

我认为不存在。

虽然 map 在返回项目不变后肯定会执行您想要的操作,但您可以将 forEach() 包装在返回数组的可链接函数中:

// add a chainable version of forEach() method to array
function addChainableForEach(array) {
  const newArr = [...array];
  Object.defineProperty(newArr, 'chainableForEach', {
    value: function(callback) {
      this.forEach(callback);
      return this;
    },
    enumerable: false
  });
  return newArr;
}

const arr = [1, 2, 3];

const arr2 = addChainableForEach(arr)
  .chainableForEach((el) => {
    console.log(`el:`, el);
  });

console.log(`arr2:`, JSON.stringify(arr2));

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-10-20
    • 2018-06-18
    • 1970-01-01
    • 1970-01-01
    • 2020-04-06
    • 2015-02-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多