javascript - 循环遍历 JSON 以按键对值进行分组

标签 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, "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"}]

在此 JSON 中共有 5 节经文。

  1. 歌曲 1,第 1 节:“Mato Joe Tsinki”/“Chiti Chiti”
  2. 歌曲 1、第 2 节:“Raro Raro”/“Shinan Kibi”/“Bewa Bewa”
  3. 歌曲 2,第 1 节:“Ramo Kano”
  4. 歌曲 2,第 2 节:“Choro Choro”
  5. 歌曲 3,第 1 节:“Pisha Pisha”

我编写了以下内容,成功打印了每首歌的第一节,但不打印后续节。

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++;
        }
}
});

更新以演示控制台日志所需的输出:

歌曲 1 第 1 节: “马托·乔·钦基” “奇蒂奇蒂”

歌曲 1 第 2 节: 《拉罗拉罗》 《吉备志南》 “贝瓦贝瓦”

歌曲 2 第 1 节: ....

最佳答案

您可以使用reduce对诗句进行分组,并使用 songverse 的每个唯一组合创建一个累加器对象,因为它是key。然后使用 Object.values得到最终的输出。这将为 songverse 的每个组合创建一个 lines 数组:

var verses = 
[{ "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"}]
 
 
 const merged = verses.reduce((acc, { song, verse, line }) => {
  const key = `${song}-${verse}`
  acc[key] = acc[key] || {song, verse, lines: []};
  acc[key]["lines"].push(line);
  return acc
 }, {})
 
 const output = Object.values(merged)
 
 console.log(output)

如果您希望用 / 分隔,则使用字符串属性并连接每个:

var verses = 
[{ "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"}]
 
 
 const merged = verses.reduce((acc, { song, verse, line }) => {
  const key = `${song}-${verse}`;
  
  if(acc[key])
    acc[key]["lines"] += " / " + line;
  else
    acc[key] = {song, verse, lines: line};
    
  return acc
 }, {})
 
 const output = Object.values(merged)
 
 console.log(output)

关于javascript - 循环遍历 JSON 以按键对值进行分组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54820073/

相关文章:

javascript - IBM Worklight - 如何将参数从应用程序传递到适配器?

javascript - 使用 jquery 的相关选择未按预期工作

javascript - 如何在 Vue.js 中将 prop 传递给父组件

javascript - 调整大小不适用于我的高度计算

javascript - Vue.js:如何连接 v-model 值

javascript - 使用 jQuery 扩展方法将函数与对象合并,为什么只返回函数?

javascript - Ajaxform在提交之前获取数据被调用

javascript - Div 未按预期显示

javascript - 更改 TypeScript 中特定键的值

javascript - vue warn - 避免直接修改 prop,因为只要父组件重新渲染,该值就会被覆盖