【问题标题】:filter is not iterating over all the elements in the array. Why?filter 没有遍历数组中的所有元素。为什么?
【发布时间】:2020-04-12 20:44:13
【问题描述】:

我想过滤返回的周数组,并将同一天与相同类型的事件分组在一起,反之亦然,另一个新数组按同一天但不同类型的事件分组

// I have created a static array with all the events
const types = ["Event", "Food", "Other", "Real Estate"];

// this is what the filtered days array returns

到目前为止,这是我能够做到的:

const filteredEqualTypes = types.map((type, i) =>
   filteredDays[i].filter(filteredDay => filteredDay.type === type)
);

...但它会在星期四之前停止,返回一个空数组,即使应该返回一个包含 2 个对象的数组,因为星期四有 2 个相等的事件

【问题讨论】:

  • 你能分享你原来filteredDays数组的JSON吗?

标签: arrays ecmascript-6 filter


【解决方案1】:

这是因为您在地图中使用了filteredDays[i],即通过索引访问filteredDays 数组。这意味着Event 仅适用于星期一,Food 仅适用于星期二,依此类推。您希望在整个 fitleredDays 数组中执行过滤,而不是在特定条目/项目中执行过滤,即 filteredDays[i]

由于您只有 4 种类型,这意味着除此之外,您只能在周三之前执行过滤——这就是为什么您看不到除此之外的任何条目。

因此,根据您的要求,您希望根据类型对事件进行分组,那么您可以执行以下操作:

  1. 遍历所有类型(您已经正确完成了)
  2. 对于每种类型,您都希望遍历整个filteredDays 数组
  3. 在每次迭代中,您都照常过滤
  4. 返回集合后,您希望将其展平,因为您返回的是原始结构(按天分组的事件)。您想要一个扁平的事件数组,而不是按天分组。这可以通过使用Array.prototype.flat 来完成。

更新代码:

const filteredEqualTypes = types.map((type) => {
  // Returns a nested array
  const entriesMatchingType = filteredDays.map((filteredDay) => {
    return filteredDay.filter((day) => day.type === type);
  });

  // Use Array.prototype.flat to flatten the nested arrays
  return entriesMatchingType.flat();
});

请参阅下面的概念验证:

const types = ["Event", "Food", "Other", "Real Estate"];
const filteredDays = [
  [{
    day_of_the_week: 'MONDAY',
    type: 'Event',
  }, {
    day_of_the_week: 'MONDAY',
    type: 'Event',
  }],
  [{
    day_of_the_week: 'TUESDAY',
    type: 'Food',
  }, {
    day_of_the_week: 'TUESDAY',
    type: 'Other',
  }, {
    day_of_the_week: 'TUESDAY',
    type: 'Food',
  }],
  [{
    day_of_the_week: 'WEDNESDAY',
    type: 'Real Estate',
  }, {
    day_of_the_week: 'WEDNESDAY',
    type: 'Other',
  }],
  [{
    day_of_the_week: 'THURSDAY',
    type: 'Other',
  }, {
    day_of_the_week: 'THURSDAY',
    type: 'Other',
  }],
  [{
    day_of_the_week: 'FRIDAY',
    type: 'Real Estate',
  }],
];

const filteredEqualTypes = types.map((type) => {
  const entriesMatchingType = filteredDays.map((filteredDay) => {
    return filteredDay.filter((day) => day.type === type);
  });
  return entriesMatchingType.flat();
});
console.log(filteredEqualTypes);

事实上,我会更进一步,建议您改用字典。那是因为无论如何你的事件类型都是独一无二的,而且更容易推理:

const eventsByType = {};
types.map((type) => {
  const events = filteredDays.map((day) => {
    return day.filter((event) => event.type === type);
  }).flat();
  eventsByType[type] = events;
});

const types = ["Event", "Food", "Other", "Real Estate"];
const filteredDays = [
  [{
    day_of_the_week: 'MONDAY',
    type: 'Event',
  }, {
    day_of_the_week: 'MONDAY',
    type: 'Event',
  }],
  [{
    day_of_the_week: 'TUESDAY',
    type: 'Food',
  }, {
    day_of_the_week: 'TUESDAY',
    type: 'Other',
  }, {
    day_of_the_week: 'TUESDAY',
    type: 'Food',
  }],
  [{
    day_of_the_week: 'WEDNESDAY',
    type: 'Real Estate',
  }, {
    day_of_the_week: 'WEDNESDAY',
    type: 'Other',
  }],
  [{
    day_of_the_week: 'THURSDAY',
    type: 'Other',
  }, {
    day_of_the_week: 'THURSDAY',
    type: 'Other',
  }],
  [{
    day_of_the_week: 'FRIDAY',
    type: 'Real Estate',
  }],
];

const eventsByType = {};
types.map((type) => {
  const events = filteredDays.map((day) => {
    return day.filter((event) => event.type === type);
  }).flat();
  eventsByType[type] = events;
});

console.log(eventsByType);

【讨论】:

  • 好的,非常感谢您的解释,还有一件小事,我想按事件分组,也可以在同一天分组,如果在星期二只有一个像“其他”这样的事件我做不希望它与 wednesday[other] 和 thursday[other] 一起,而是作为一个单独的元素。这可能吗?
  • 如果你还想在白天嵌套它们,那么只需删除使用.flat()的需要。
  • 太棒了,再次感谢,我已将您的答案标记为正确的答案
【解决方案2】:

您需要遍历filteredDays,而不是迭代类型,以映射所有天数,而不仅仅是等于有效类型长度的天数

const res = filteredDays.map(day => day.filter(val => types.includes(val.type)));

【讨论】:

    猜你喜欢
    • 2020-07-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-11-25
    • 2011-05-24
    • 2020-02-04
    • 2019-12-24
    • 1970-01-01
    相关资源
    最近更新 更多