为何Lodash的_.union方法无法向空数组添加单个元素?
问题:Lodash
_.union 更新PostgreSQL空数组时,单个元素无法插入,多元素正常? 我用Lodash的_.union更新PostgreSQL的空数组时遇到异常:添加单个元素后数组仍为空,但添加2个及以上元素完全正常。
相关代码
Sequelize产品模型定义
variation: { type: DataTypes.ARRAY(DataTypes.STRING), defaultValue: [], allowNull: true, },
业务代码
const id = req.params.id; const { variation } = req.body; const isVariation = await products.findOne({ where: { product_id: id }, }); const variationArray = isVariation.variation; let newlist = _.union(variationArray, variation); await products.update( { variation: newlist}, { where: { product_id: id } } );
正常运行的测试代码
let arr = []; let ok = _.union(arr, ["1"]) console.log(ok); // 输出 ["1"]
问题根源
核心问题是前端传递的单个元素参数类型不符合预期:
- 传递多元素时,前端通常会把参数包装成数组(如
["red", "blue"]),_.union能正常合并两个数组,更新也能成功。 - 传递单个元素时,前端可能直接传了字符串/单个值(如
"red")而非数组。此时虽然_.union([], "red")会返回["red"],但Sequelize在处理ARRAY类型字段时,若收到单个值而非数组,可能无法正确转换为PostgreSQL的数组格式,导致最终存储的数组仍为空;如果前端传递的参数是undefined或空值,合并后自然还是空数组。
解决方案
统一将req.body.variation转换为数组格式,确保无论前端传单个值还是数组,都能正确处理:
const id = req.params.id; const { variation } = req.body; const isVariation = await products.findOne({ where: { product_id: id }, }); const variationArray = isVariation.variation; // 统一转换为数组,排除空值/undefined const variationToAdd = Array.isArray(variation) ? variation : (variation != null ? [variation] : []); let newlist = _.union(variationArray, variationToAdd); await products.update( { variation: newlist}, { where: { product_id: id } } );
也可以用原生JS实现去重合并,无需依赖Lodash:
const variationToAdd = Array.isArray(variation) ? variation : (variation != null ? [variation] : []); const newlist = [...new Set([...variationArray, ...variationToAdd])];
额外排查建议
- 打印
req.body.variation和newlist的值,确认参数类型和合并结果是否符合预期。 - 要求前端在传递单个元素时,也统一用数组格式(如
["red"]),从源头避免类型问题。
内容的提问来源于stack exchange,提问作者sumanth.js
相关产品推荐
相关产品推荐

