如何使用JavaScript或节点分组JSON?

我有一个JSON的音乐audio元数据在以下结构中的几个轨道:

var jsonObj = { tracks: [ { title: 'Another', artist: 'Ataxia', album: 'Automatic Writing', year: '2004', duration: 382 }] }; 

我想将其转换为具有以下分组结构:

 var jsonObj = { artists: [ { name: 'Ataxia', albums: [ { name: 'Automatic Writing', year: '2004', tracks: [ { title: 'Another', duration: '382' }] }] }] }; 

当然,我尝试使用纯JavaScript JavaScript forEach()方法,但它是一个重复的,身临其境的代码,我正在寻找一些聪明的解决scheme。 它可以依靠一些外部的Node.js包或JavaScript库。

结合艺术家和专辑的简单方法是使用字典。 这是通过字典处理数据的一种方法,然后一旦按专辑和艺术家组织曲目,就会生成所需的数组。 在控制台中查看结果。

 var jsonObj = { tracks: [{ title: 'Another', artist: 'Ataxia', album: 'Automatic Writing', year: '2004', duration: 382 }] }; var byArtist = {}; jsonObj.tracks.forEach(function(e) { if (byArtist[e.artist] === undefined) { // New artist, add to the dictionary byArtist[e.artist] = { artist: e.artist, albums: {} }; } if (byArtist[e.artist].albums[e.album] == undefined) { // New album, add to the dictionary byArtist[e.artist].albums[e.album] = { name: e.album, year: e.year, tracks: [] }; } // Add the track byArtist[e.artist].albums[e.album].tracks.push({ title: e.title, duration: e.duration }); }); // Convert the dictionaries to the final array structure var result = { artists: [] }; for (var artistKey in byArtist) { if (byArtist.hasOwnProperty(artistKey)) { var artist = { name: byArtist[artistKey].artist, albums: [] }; // We need to convert the album dictionary as well for (var albumKey in byArtist[artistKey].albums) { if (byArtist[artistKey].albums.hasOwnProperty(albumKey)) { artist.albums.push(byArtist[artistKey].albums[albumKey]); } } result.artists.push(artist); } } console.log(result); 

你可以做如下的事情(你需要看看控制台才能看到结果):

 var jsonObj = { tracks: [ { title: 'Another', artist: 'Ataxia', album: 'Automatic Writing', year: '2004', duration: 382 }] }; var jsonObjResult = {}; jsonObj['tracks'].forEach(function(track, index){ jsonObjResult['artists'] = []; jsonObjResult['artists'][index] = { 'name' : track['artist'] , 'albums' : [] }; jsonObjResult['artists'][index]['albums'] = { 'name' : track['album'] , 'year' : track['year'] , 'tracks' : [] }; jsonObjResult['artists'][index]['albums']['tracks'] = { 'title' : track['title'] , 'duration' : track['duration'] }; }); console.log(jsonObjResult); 

当我正在把它变成所需的格式时,我不得不寻找一位艺术家,寻找一张专辑,寻找一首曲目等等。所以,想到这一点,我意识到你可能会想要这些function你自己在最后的数据结构上,而不是只是把一个代码转换成另一个代码,而是把所得到的音乐列表变成一个有着不同方法的对象。 其中一种方法会将音轨列表添加到音乐列表中,并按照您的要求进行组织。

所以,这是对象和结果演示。 为了更好地显示结果,我添加了更多的曲目。 最终的结果是你得到一个包含音乐列表的对象,并且你可以findfind艺术家,专辑和曲目的方法。

 var trackList = { tracks: [ { title: 'Another', artist: 'Ataxia', album: 'Automatic Writing', year: '2004', duration: 382 }, { title: 'Another2', artist: 'Ataxia', album: 'Automatic Writing', year: '2007', duration: 412 }, { title: 'Another3', artist: 'Ataxia3', album: 'Automatic Writing', year: '2008', duration: 366 }, ] }; function Music() { this.artists = []; } // helper function // In an array of objects, it finds an object that has a specific property name // with a specific value. function findPropInArray(arr, propName, propValue) { for (var i = 0; i < arr.length; i++) { if (arr[i][propName] === propValue) { return arr[i]; } } return null; } Music.prototype = { addTracks: function(list) { var self = this; list.forEach(function(t) { self.addTrack(t); }); }, addTrack: function(t) { if (t.artist) { var artistObj = this.findArtist(t.artist); if (!artistObj) { // if artist not found, then add the artist artistObj = {name: t.artist, albums: []}; this.artists.push(artistObj); } var albumObj = this.findAlbum(artistObj, t.album); if (!albumObj) { // create album Obj albumObj = {name: t.album, year: t.year, tracks: []}; artistObj.albums.push(albumObj); } if (!this.findTrack(albumObj, t.title)) { albumObj.tracks.push({title: t.title, duration: t.duration}); } } }, findArtist: function(name) { return findPropInArray(this.artists, "name", name); }, findAlbum: function(artist, albumName) { var artistObj = artist; // if artist name was passed as a string, then find the object if (typeof artist === "string") { artistObj = this.findArtist(artist); } if (!artistObj) { return null; } return findPropInArray(artistObj.albums, "name", albumName); }, findTrack: function(albumObj, name) { return findPropInArray(albumObj.tracks, "title", name); } } var m = new Music(); m.addTracks(trackList.tracks); var text = JSON.stringify(m, null, " "); document.getElementById("result").textContent = text; 
 <pre id="result"></pre>