Javascript 通过JSON循环按键对值进行分组

Javascript 通过JSON循环按键对值进行分组,javascript,Javascript,我有一个JSON文件,其中包含一组歌曲,以及相关的歌曲行、诗句编号等。我的目标是打印每个不同的诗句。我很难构建一个有效的循环。以下是JSON文件的示例: [{ "song": 1, "verse": 1, "lineNum": 1, "line": "Mato Joe Tsinki"}, { "song": 1, "verse": 1, "lineNum": 2, "line": "Chiti chiti"}, { "song": 1, "verse": 2, "lineNum": 1, "

我有一个JSON文件,其中包含一组歌曲,以及相关的歌曲行、诗句编号等。我的目标是打印每个不同的诗句。我很难构建一个有效的循环。以下是JSON文件的示例:

[{ "song": 1, "verse": 1, "lineNum": 1, "line": "Mato Joe Tsinki"},
 { "song": 1, "verse": 1, "lineNum": 2, "line": "Chiti chiti"},
 { "song": 1, "verse": 2, "lineNum": 1, "line": "Raro Raro"},
 { "song": 1, "verse": 2, "lineNum": 2, "line": "Shinan Kibi"},
 { "song": 1, "verse": 2, "lineNum": 3, "line": "Bewa bewa"},
 { "song": 2, "verse": 1, "lineNum": 1, "line": "Ramo Kano"},
 { "song": 2, "verse": 2, "lineNum": 1, "line": "Choro Choro"},
 { "song": 3, "verse": 1, "lineNum": 1, "line": "Pisha Pisha"}]
本节共有5节

  • 歌曲1,第1节:“马托乔·钦基”/“奇蒂奇蒂”
  • 歌曲1,第2节:“拉罗·拉罗”/“希南·基比”/“贝瓦·贝瓦”
  • 第二首歌,第1节:“拉莫·卡诺”
  • 第二首歌,第二节:“Choro Choro”
  • 第三首歌,第1节:“比萨比萨”
  • 我已经写了以下内容,成功地打印了每首歌的第一节,但没有后续的诗句

    var fs = require('fs');
    var colors = require('colors');
    fs.readFile('stackoverflow.json', 'utf8', function (err,data) {
    data = JSON.parse(data); 
    
    for(var i in data) { 
        var item = data[i];
        // construct string song:verse:line
        var lineIndex = item.song   
        lineIndex += ":"+item.verse
        lineIndex += ":"+item.lineNum
    
        var numSongs = 20
        var songNum = 1
        var verseNum = 1
        var lineNum = 1
        // console.log(verseNum)
    
            while(item.song <= numSongs && item.verse == verseNum)
            {       
                console.log(lineIndex.green + ' ' + item.line);
                verseNum++;
            }
    }
    });
    
    var fs=require('fs');
    var colors=需要(“颜色”);
    fs.readFile('stackoverflow.json','utf8',函数(err,data){
    data=JSON.parse(数据);
    对于(数据中的变量i){
    var项目=数据[i];
    //构造弦乐曲:诗:线
    var lineIndex=item.song
    lineIndex+=“:”+item.verse
    lineIndex+=“:”+item.lineNum
    var numSongs=20
    var songNum=1
    var verseNum=1
    var lineNum=1
    //console.log(verseNum)
    
    当(<宋> P>而不是使用<代码>而<代码/>和<>代码> 时,考虑使用.< /P> 作为带有
    line
    lineNum
    行的数组:

    var arr=[{“歌曲”:1,“诗句”:1,“诗句”:1,“诗句”:1,“诗句”:1,“诗句”:2,“诗句”:2,“诗句”:2,“诗句”:1,“诗句”:2,“诗句”:1,“诗句”:2,“诗句”:2,“诗句”:2,“诗句”:2,“诗句”:3,“诗句”:3,“诗句:{“诗句”:2,{“诗句”},{,“诗句”:1,“诗行”:1,“诗行”:“拉莫·卡诺”},{“歌曲”:2,“诗行”:2,“诗行”:1,“诗行”:“合唱”},{“歌曲”:3,“诗行”:1,“诗行”:“比萨·比萨”};
    让结果=arr.reduce((out,i)=>{
    让我们找到它(s=>s.song==i.song&&s.verse==i.verse);
    设{line,lineNum,…newSong}=i;
    让{歌,诗,…新行}=i;
    建立
    ?找到.行.推送(换行)
    :out.push({…新闻歌曲,行:[newLine]});
    返回;
    }, []);
    console.log(result);
    您可以使用来对诗句进行分组,并创建一个累加器对象,每个独特的
    歌曲和
    诗句组合都是
    键,然后使用来获得最终输出。这将为
    歌曲和
    诗句的每个组合创建一个
    行的数组:

    var-verses=
    [{“歌”:1,“诗”:1,“行”:1,“行”:“马托·乔·钦基”},
    {“歌曲”:1,“诗句”:1,“诗行”:2,“诗行”:“奇蒂奇蒂”},
    {“歌”:1,“诗”:2,“行”:1,“行”:“Raro Raro”},
    {“歌曲”:1,“诗句”:2,“诗行”:2,“诗行”:“Shinan Kibi”},
    {“歌曲”:1,“诗句”:2,“诗行”:3,“诗行”:“Bewa Bewa”},
    {“歌”:2,“诗”:1,“行”:1,“行”:“拉莫·卡诺”},
    {“歌”:2,“诗”:2,“行”:1,“行”:“合唱”},
    {“歌”:3,“诗”:1,“行”:1,“行”:“比萨比萨”}]
    const merged=verses.reduce((acc,{song,verse,line})=>{
    常量键=`${song}-${verse}`
    acc[key]=acc[key]|{歌曲、韵文、诗句:[]};
    acc[键][“行”]。按(行);
    返回acc
    }, {})
    常量输出=对象值(合并)
    
    console.log(output)
    这里有另一个版本,它使用first按
    song
    韵文对行进行分组,首先将它们按顺序放在数组上(以防原始数组未排序)。然后我们使用它来获得预期的输出:

    让输入=[
    {“歌曲”:1,“诗句”:1,“诗行”:2,“诗行”:“奇蒂奇蒂”},
    {“歌曲”:1,“诗句”:1,“诗行”:1,“诗行”:“马托乔·钦基”},
    {“歌”:1,“诗”:2,“行”:1,“行”:“Raro Raro”},
    {“歌曲”:1,“诗句”:2,“诗行”:3,“诗行”:“Bewa Bewa”},
    {“歌曲”:1,“诗句”:2,“诗行”:2,“诗行”:“Shinan Kibi”},
    {“歌”:2,“诗”:1,“行”:1,“行”:“拉莫·卡诺”},
    {“歌”:2,“诗”:2,“行”:1,“行”:“合唱”},
    {“歌”:3,“诗”:1,“行”:1,“行”:“比萨比萨”}
    ];
    让诗句={};
    input.forEach(o=>
    {
    设k=`o.song}{o.verse}`;
    诗[k]=诗[k]|{歌:歌,诗:诗};
    第[k][“行”]=第[k][“行”]| |[];
    诗句[k][“行”][o.lineNum]=o.line;
    });
    设res=Object.values(韵文).map(
    o=>`song${o.song},verse${o.verse},行:${o.lines.filter(布尔值)。join(“/”)`
    );
    
    console.log(res);
    你好,Dave,在我键入答案之前,您是否有权访问lodash库(或下划线)在您的项目中?您也可以使用ecmascript 6吗?仅供参考:我可以使用其他库,如lodash。感谢您的快速回复。Adiga,基于verse的分组。@Dave这到底是什么?字符串数组?多个
    console.log()
    s?一个带换行符的长字符串?这并不能让它变得更清晰。所需的输出应该用代码表示,就像您的输入数组一样。谢谢Tyler。我用所需的输出更新了问题。