1

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' } 
  ] } ] } ] 

2 Answers 2

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

Sign up to request clarification or add additional context in comments.

Comments

0

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.