JavaScript求助:如何根据第三个数组筛选并生成新数组
问题解决:筛选匹配项并添加对应日期
你的场景与问题
你手头有两个数组:
- 存储表单数据的
structuredFormData:
[ { "season": "autumn", "firstContactPersonName": "John", "firstContactPersonPhone": "46442644", "secondContactPersonName": "Jhonny", "secondContactPersonPhone": "46442644" }, { "season": "christmas", "firstContactPersonName": "Tommy", "firstContactPersonPhone": "46442644", "secondContactPersonPhone": "Thomas" } ]
- 存储季节与日期映射的
selectedDate,格式是["season=date"]:- 单日期场景:
["autumn=2020-08-28"] - 多日期场景:
["autumn=2020-08-28", "christmas=2020-12-28"]
- 单日期场景:
你原本写了一段代码想生成带日期的新数组,但遇到了问题:当selectedDate只有单个日期时,你希望新数组只保留匹配到对应季节的那一项,而不是原数组所有项都保留(没匹配到的项还会因为find返回undefined报错)。需要实现:
- 单日期时,输出仅包含对应匹配项且带日期的数组
- 多日期时,输出对应两个带日期的对象数组
解决方案:先筛选再映射
核心思路是先从structuredFormData里筛选出和selectedDate中季节匹配的项,再给这些项添加日期。这样既避免了找不到匹配项的报错,也能自动过滤掉不需要的项。
第一步:把selectedDate转成键值对对象(方便快速查找)
先把selectedDate数组转成键为季节、值为日期的对象,比如{ autumn: "2020-08-28", christmas: "2020-12-28" },这样后续查找日期会更高效,也更直观。
第二步:筛选+映射结合
用filter先筛选出存在于日期对象中的季节项,再用map添加日期。另外建议不要修改原数组(如果需要保留原数组的话),可以用对象展开运算符{...x}创建新对象,避免副作用。
完整代码如下:
// 先把selectedDate转成键值对对象 const dateMap = selectedDate.reduce((acc, item) => { const [season, date] = item.split("="); acc[season] = date; return acc; }, {}); // 筛选匹配的项并添加日期 const updatedStructuredFormData = structuredFormData .filter(item => dateMap.hasOwnProperty(item.season)) // 只保留有对应日期的项 .map(item => ({ ...item, // 复制原对象的所有属性 date: dateMap[item.season] // 添加日期属性 }));
代码细节解释:
reduce方法把selectedDate数组转成对象,这样后续查找日期的时间复杂度是O(1),比你原来用find的O(n)更高效,尤其是当数组元素多的时候差异更明显。filter方法会过滤掉structuredFormData中季节不在dateMap里的项,完美实现你要的“只保留匹配项”的需求。map里用{...item}创建原对象的副本,再添加date属性,这样不会修改原数组的对象(如果不需要保留原数组,也可以直接修改原对象,但推荐创建新对象,避免意外修改原数据)。
测试验证:
- 当
selectedDate = ["autumn=2020-08-28"]时,输出结果完全符合你的预期:
[ { "season": "autumn", "firstContactPersonName": "John", "firstContactPersonPhone": "46442644", "secondContactPersonName": "Jhonny", "secondContactPersonPhone": "46442644", "date": "2020-08-28" } ]
- 当
selectedDate包含两个日期时,输出两个带日期的对象,完全满足需求。
另外,如果你的场景中selectedDate的格式可能出现错误(比如某个项不能正确split成季节和日期),可以在reduce里加个简单判断,比如:
const dateMap = selectedDate.reduce((acc, item) => { const parts = item.split("="); if (parts.length === 2) { const [season, date] = parts; acc[season] = date; } return acc; }, {});
这样就能跳过格式错误的项,避免程序报错。
内容的提问来源于stack exchange,提问作者user13089222
相关产品推荐
相关产品推荐

