React中使用map转换JSON为CSV时,如何将数组内容按行分隔而非逗号分隔?
我明白你的需求了——现在导出的CSV里,每个音频包(pack)对应的多个音频(sound)信息都挤在同一行的数组里,你希望每个音频单独占一行,同时保留对应的包信息对吧?咱们可以通过重构数据生成逻辑来实现这个效果,具体步骤如下:
1. 重构数据生成逻辑,展开音频数组
原来的data是把每个pack转成一行,但每个pack里的pack_sounds_ids是数组,导致所有sound的信息都变成数组字段。现在我们需要遍历每个pack,再遍历它的每个sound,把每个sound单独生成一个对象,同时带上pack的公共信息(包ID、包名称)。
替换你原来的data变量代码:
// 展开每个pack下的sound,每个sound生成一行CSV数据 const data = value.flatMap(pack => { // 遍历当前pack下的每一个音频 return pack.pack_sounds_ids.map(sound => { return { _id: pack._id, // 包ID,每个音频行重复该值 pack_name: pack.pack_name, // 包名称,每个音频行重复该值 _id_sound: sound._id, // 单个音频的ID chord_att_value: sound.chord_type_id?.att_value || '', // 单个音频的和弦类型 // 将乐器数组转成逗号分隔的字符串(如果需要每个乐器单独成行,后面会补充处理方式) instrumendts_att_value: sound.instruments_ids?.map(ele => ele.att_value).join(', ') || '', key_att_value: sound.key_id?.att_value || '', maininstrument_att_value: sound.maininstrument_id?.att_value || '', product_att_value: sound.product_type_id?.att_value || '', refrence_att_value: sound.references_ids?.map(ele => ele.att_value).join(', ') || '', root_att_value: sound.root_note_id?.att_value || '', sound_bpm: sound.sound_bpm, sound_index: sound.sound_index, sound_name: sound.sound_name, tags_att_value: sound.tags_ids?.map(ele => ele.att_value).join(', ') || '' }; }); });
这里用了flatMap,它会把每个pack返回的sound数组扁平化,最终得到一个包含所有sound的一维数组,每个元素对应CSV的一行。另外加了可选链?.避免空值报错,把嵌套数组(比如乐器、标签)转成逗号分隔的字符串——如果你的需求是这些嵌套数组的每个元素也要单独成行(比如一个sound有2个乐器,就生成2行,其他字段重复),可以用下面的补充方案。
补充:如果嵌套数组(如乐器、标签)也要单独成行
如果需要把sound里的数组字段(比如标签)也拆成单独行,其他字段保持重复,那需要再嵌套一层flatMap,以标签为例:
const data = value.flatMap(pack => { return pack.pack_sounds_ids.flatMap(sound => { // 如果标签数组存在,就每个标签生成一行;否则生成一行空标签 const tags = sound.tags_ids?.map(ele => ele.att_value) || ['']; return tags.map(tag => { return { _id: pack._id, pack_name: pack.pack_name, _id_sound: sound._id, chord_att_value: sound.chord_type_id?.att_value || '', instrumendts_att_value: sound.instruments_ids?.map(ele => ele.att_value).join(', ') || '', key_att_value: sound.key_id?.att_value || '', maininstrument_att_value: sound.maininstrument_id?.att_value || '', product_att_value: sound.product_type_id?.att_value || '', refrence_att_value: sound.references_ids?.map(ele => ele.att_value).join(', ') || '', root_att_value: sound.root_note_id?.att_value || '', sound_bpm: sound.sound_bpm, sound_index: sound.sound_index, sound_name: sound.sound_name, tags_att_value: tag }; }); }); });
这样一个带3个标签的sound会生成3行,每行仅标签字段不同,其余字段和该sound的信息一致。
2. 调整Headers配置(可选,更规范)
现在每个字段都是单个值了,你可以保持原headers不变,也可以微调标签让它更清晰:
const headers = [ {label:"Pack ID", key:"_id"}, {label:"Sound ID", key:"_id_sound"}, {label:"Pack Name", key:"pack_name"}, {label:"Chord", key:"chord_att_value"}, {label:"Instruments", key:"instrumendts_att_value"}, {label:"Key", key:"key_att_value"}, {label:"Main Instrument", key:"maininstrument_att_value"}, {label:"Product Type", key:"product_att_value"}, {label:"References", key:"refrence_att_value"}, {label:"Root Note", key:"root_att_value"}, {label:"BPM", key:"sound_bpm"}, {label:"Index", key:"sound_index"}, {label:"Sound Name", key:"sound_name"}, {label:"Tags", key:"tags_att_value"}, ];
修改完成后,点击下载按钮导出的CSV就会把每个sound单独拆分成一行,数组类型的字段也会按照你的需求处理,不会再挤在同一行里。
内容的提问来源于stack exchange,提问作者hemendra

