首页 > 解决方案 > 一次数组多个过滤器和变量赋值

问题描述

我有以下forEach声明:

reviews.forEach(review => {
    if (review.timestamp >= beforeThreeMonthsDate) {
        lastThreeMonths.push(review);
    }
    if (review.timestamp >= beforeSixMonthsDate) {
        lastSixMonths.push(review);
    }
    if (review.timestamp >= beforeOneYearDate) {
        lastYear.push(review);
    }
    if (review.timestamp >= beforeTwoYearsDate) {
        lastTwoYear.push(review);
    }
});

有没有办法通过使用或任何新的ES6功能在列表中循环一次来获得相同的结果reviewsfilter

标签: javascriptarraysfilter

解决方案


它会稍微改变输出,但是您可以reduce更改为对象。而不是 4 个单独的变量。

const {
  lastThreeMonths,
  lastSixMonths,
  lastYear,
  lastTwoYear
} = reviews.reduce(
  (groups, review) => {
    if (review.timestamp >= beforeThreeMonthsDate) {
      groups.lastThreeMonths.push(review);
    }
    if (review.timestamp >= beforeSixMonthsDate) {
      groups.lastSixMonths.push(review);
    }
    if (review.timestamp >= beforeOneYearDate) {
      groups.lastYear.push(review);
    }
    if (review.timestamp >= beforeTwoYearsDate) {
      groups.lastTwoYear.push(review);
    }
  },
  { lastThreeMonths: [], lastSixMonths: [], lastYear: [], lastTwoYear: [] }
);

这真的很像一个groupBy函数。

但我会考虑如何使用这些信息。如果是用于视图层,我会考虑排序,然后使用takeUntil类型函数来提高灵活性。如果您需要lastWeeklastDay那么以前的和原始的解决方案可能会变得笨拙。

const takeUntil = (pred, list) =>
  list.reduce((taken, next) => (pred(next) ? taken.concat(next) : taken), []);
const sinceTwoDays = takeUntil(review => review.timestamp >= twoDaysAgo, reviews);

这种方式至少循环 2 次,但它提供了很多未来的灵活性。您可以传递任何日期并返回它。


推荐阅读