Javascript/nodejs dynamically build JS object with nested arrays

你说的曾经没有我的故事 提交于 2021-01-28 12:52:20

问题


I have an array of Js objects like this:

const source = 
  [ { title: 'Expanse', season: 1, episode: 1, path: 'download.mkv' } 
  , { title: 'Expanse', season: 1, episode: 2, path: 'download.mkv' } 
  , { title: 'GoT',     season: 7, episode: 1, path: 'download.mkv' } 
  , { title: 'GoT',     season: 8, episode: 1, path: 'download.mkv' } 
  , { title: 'GoT',     season: 8, episode: 4, path: 'download.mkv' } 
  ] 

I'm trying to read this array and create one object the will hold all the data, like this: so from each node, i can easily retrieve all the relevant data.
I've been trying to do this for a few days, but cant seem to get it to work, PLEASE HELP a NUBE! at the beging I thought I could just do

videos["Expanse"]["season"]["episode"]["path"] = "..."  

it will create all the keys (kind of like firebase realtime database but apparently it not as easy)

const videos = 
  [ { title: 'Expanse', seasons: 
      [ { season: 'season 1', episodes: 
          [ { name: 'episode 1', path: 'download.mkv' } 
          , { name: 'episode 2', path: 'download.mkv' } 
    ] } ] } 
  , { title: 'GoT', seasons: 
      [ { season: 'season 7', episodes: 
          [ { name: 'episode 1', path: 'download.mkv' } 
        ] } 
      , { season: 'season 8', episodes: 
          [ { name: 'episode 1', path: 'download.mkv' } 
          , { name: 'episode 4', path: 'download.mkv' } 
  ] } ] } ] 

回答1:


"simply" this way...

const source = 
  [ { title: 'Expanse', season: 1, episode: 1, path: 'download.mkv'} 
  , { title: 'Expanse', season: 1, episode: 2, path: 'download.mkv'} 
  , { title: 'GoT', season: 7, episode: 1, path: 'download.mkv'} 
  , { title: 'GoT', season: 8, episode: 1, path: 'download.mkv'} 
  , { title: 'GoT', season: 8, episode: 4, path: 'download.mkv'} 
  ]
  
const result = source.reduce((a,{title,season,episode,...more} )=>
  {
  let titleX = a.find(x=>x.title===title)
  if (!titleX)
    {
    titleX = { title, seasons:[] }
    a.push(titleX)
    }
  let seasonX = titleX.seasons.find(x=>x.season===`season ${season}`)
  if (!seasonX)
    {
    seasonX = { season:`season ${season}`, episodes:[] }
    titleX.seasons.push(seasonX)
    }
  seasonX.episodes.push({ name:`episode ${episode}`, ...more })
  return a  
  },[])

  
console.log(  result )
.as-console-wrapper { max-height: 100% !important; top: 0; }



回答2:


You could use reduce and create intermediary functions along these lines:

function buildStructure(source) {
  return {
    videos: source.reduce((res, episode) => {
      let show = res.find(s => s.title === episode.title);
      if (!show) {
        show = { title: episode.title, seasons: [] };
        res.push(show);
      }
      addEpisodeToShow(show, episode);
      return res;
    }, [])
  };
}

function addEpisodeToShow(show, episode) {
  let season = show.seasons.find(s => s.season === `season ${episode.season}`);
  if (!season) {
    season = { season: `season ${episode.season}`, episodes: [] };
    show.seasons.push(season);
  }
  addEpisodeToSeason(season, episode);
  show.seasons.sort(compareFactory('season'));
}

function addEpisodeToSeason(season, episode) {
  season.episodes.push({
    name: `episode ${episode.episode}`,
    path: episode.path
  });
  season.episodes.sort(compareFactory('name'));
}

function compareFactory(key) {
  return function(a, b) {
    var _a = +(a[key].replace(/\D/g, '')),
        _b = +(b[key].replace(/\D/g, ''));
    return _a - _b;
  }
}

const source = [
  {"title": "Expanse", "season": 1, "episode": 1, "path": "download.mkv" },
  {"title": "GoT", "season": 8, "episode": 4, "path": "download.mkv" },
  {"title": "Expanse", "season": 1, "episode": 2, "path": "download.mkv" },
  {"title": "GoT", "season": 7, "episode": 1, "path": "download.mkv" },
  {"title": "GoT", "season": 8, "episode": 1, "path": "download.mkv" }
];
console.log( buildStructure(source) );
.as-console-wrapper { max-height: 100% !important; }


来源:https://stackoverflow.com/questions/65401527/javascript-nodejs-dynamically-build-js-object-with-nested-arrays

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!