如何按指定零售商顺序格式化食材数组以导出CSV?
实现食材数组到指定格式CSV的转换
原始数据
给定食材对象数组:
const ingredients = [ { name: 'Gluten Free Oats', retailer_id: 4, link: 'targetlink' }, { name: 'Gluten Free Oats', retailer_id: 3, link: 'amazonlink' }, { name: 'Adobo Seasoning', retailer_id: 50, link: 'walmartlink' }, { name: 'Adobo Seasoning', retailer_id: 3, link: 'amazonlink' }, { name: 'Adobo Seasoning', retailer_id: 4, link: 'targetlink' }, { name: 'Adobo Seasoning', retailer_id: 135, link: 'krogerlink' }, { name: 'America Cheese Spread', retailer_id: 3, link: 'amazonlink' }, { name: 'Au Jus Gravy Mix', retailer_id: 68, link: 'wholefoodslink' } ];
零售商ID顺序及对应名称:
// 顺序数组 const order = [3, 4, 50, 68, 135]; // ID与名称映射 const retailerMap = { 3: 'Amazon', 4: 'Target', 50: 'Walmart', 68: 'Whole Foods', 135: 'Kroger' };
需求说明
需生成无重复食材名称的CSV,满足:
- 表头第一列为
Ingredient Name,后续列按order数组指定的零售商顺序排列 - 每个食材对应各零售商的链接,无匹配则填充
null - 同一零售商有多条链接时,用双引号包裹所有链接(逗号分隔)
实现代码
// 1. 按食材名称分组,整理各零售商的链接数组 const groupedIngredients = ingredients.reduce((acc, item) => { const { name, retailer_id, link } = item; if (!acc[name]) acc[name] = {}; acc[name][retailer_id] = acc[name][retailer_id] ? [...acc[name][retailer_id], link] : [link]; return acc; }, {}); // 2. 生成CSV表头 const header = ['Ingredient Name', ...order.map(id => retailerMap[id])].join(','); // 3. 生成每一行的内容 const rows = Object.entries(groupedIngredients).map(([name, retailerLinks]) => { const linkColumns = order.map(retailerId => { const links = retailerLinks[retailerId]; if (!links) return 'null'; return links.length > 1 ? `"${links.join(',')}"` : links[0]; }); return [name, ...linkColumns].join(','); }); // 4. 拼接最终CSV字符串 const csv = [header, ...rows].join('\n'); // 输出结果 console.log(csv);
代码说明
- 分组处理:使用
reduce将相同名称的食材归为一组,每组内以零售商ID为键存储对应的链接数组,自动处理同一零售商多链接的场景。 - 表头生成:根据
order数组的顺序,映射出对应的零售商名称,与Ingredient Name拼接成表头。 - 行内容生成:遍历每个食材分组,按
order顺序依次获取各零售商的链接,无链接则填null,多链接则用双引号包裹。 - CSV拼接:将表头和所有行用换行符连接,得到符合要求的CSV格式字符串。
匹配示例表头的调整
若需要完全匹配你给出的示例表头顺序(Ingredient Name,Amazon,Kroger,Target,Walmart,Whole Foods),只需将order数组调整为:
const order = [3, 135, 4, 50, 68];
内容的提问来源于stack exchange,提问作者Marko Nikolov
相关产品推荐
相关产品推荐

