0

I have a nested object containing years and a publication identifier. How do I list the publications by year, latest to earliest? I read here that order of objects is predictable as of ES6. In my code, I have a function that produces a dropdown list of years (addOption) and another that populates a div with the publications for the selected year or all years (populatePubs). If a user selects all years, the publications are presented in order from earliest to latest (ascending), but I want the publications to display in reverse chronological order. Is there a built-in JavaScript object method that can do this?

const testPubs = {
  2019 : {
    '19-6N': {
      'author' : 'jimbo',
      'title' : 'test title'
    },
    '19-7N': {
      'author' : 'jimmy',
      'title' : 'test title 2'
    }
  },
  2018 : {
    '18-6N': {
      'author' : 'joey',
      'title' : 'test title'
    },
    '18-7N': {
      'author' : 'jeffy',
      'title' : 'test title 2'
    }
  },
  2017 : {
    '17-6N': {
      'author' : 'bob',
      'title' : 'test title'
    },
    '17-7N': {
      'author' : 'bobby',
      'title' : 'test title 2'
    }
  },
}

const startYear = 1984;
const currentYear = new Date().getFullYear();

function addOption() { // adds years to dropdown menu
  const select = document.querySelector('#selectYears');
  let blank_option = document.createElement("option");
  blank_option.setAttribute("selected", true);
  blank_option.setAttribute("disabled", true);
  blank_option.textContent = `Year`;
  select.appendChild(blank_option);
  for (let i = currentYear; i >= startYear; i--){
    let option = i;
    let el = document.createElement("option");
    el.textContent = option;
    select.appendChild(el);
  }
  const allYears = document.createElement("option");
  allYears.textContent = `All Years`;
  select.appendChild(allYears)
}
addOption(); // add years dropdown

function populatePubs(year){
  const pubsForYear = document.querySelector("#pubsByYear");
  pubsByYear.class = year;
  while (pubsForYear.firstChild){
    pubsByYear.removeChild(pubsByYear.firstChild);
  }
  if (year in testPubs){
    for (let pub in testPubs[year]){ // add publications for specified year
      let doc = document.createElement("div");
      doc.id = pub;
      doc.textContent = `${testPubs[year][pub].author} - ${testPubs[year][pub].title} - ${pub}`;
      pubsByYear.appendChild(doc);
  }
} else if (year === 'All Years') { // need to ensure order of object is descending
    for (let yr in testPubs){ // add publications for all years
        const yearHeader = document.createElement("h4");
        yearHeader.innerText = yr;
        pubsByYear.appendChild(yearHeader);
      if (typeof testPubs[yr] === 'object'){
        for (let pub in testPubs[yr]) {
          pubsByYear.class = `All Years`;
          const doc = document.createElement("div");
          doc.id = testPubs[yr][pub];
          doc.textContent = `${testPubs[yr][pub].author} - ${testPubs[yr][pub].title} - ${pub}`;
          pubsByYear.appendChild(doc);
        }
      }
    }
  }
}
<!DOCTYPE html>
<html lang="en" dir="ltr">
  <head>
    <meta charset="utf-8">
    <title>Test Publications by Year</title>
  <body>
  <!-- years dropdown -->
  <select id="selectYears" onchange="populatePubs(this.value)"></select>
  <!-- display current year -->
  <div id="pubsByYear" class="year"></div>
  <script src="script.js"></script>
  </body>
</html>

2
  • Looks like this has already been answered here: stackoverflow.com/questions/18412214/… although this is kind of an old post Commented Dec 17, 2019 at 18:24
  • var opposite = Object.entries(testPubs).reverse() Commented Dec 17, 2019 at 18:54

1 Answer 1

1

You could just use the built in reverse method on arrays in combination with the Object.keys method :

function populatePubs(year) {
  const pubsForYear = document.querySelector("#pubsByYear");
  pubsByYear.class = year;
  while (pubsForYear.firstChild) {
    pubsByYear.removeChild(pubsByYear.firstChild);
  }
  if (year in testPubs) {
    for (let pub in testPubs[year]) { // add publications for specified year
      let doc = document.createElement("div");
      doc.id = pub;
      doc.textContent = `${testPubs[year][pub].author} - ${testPubs[year][pub].title} - ${pub}`;
      pubsByYear.appendChild(doc);
    }
  } else if (year === 'All Years') { // need to ensure order of object is descending
    const years = Object.keys(testPubs).reverse();
    for (let yr of years) { // add publications for all years
      const yearHeader = document.createElement("h4");
      yearHeader.innerText = yr;
      pubsByYear.appendChild(yearHeader);
      if (typeof testPubs[yr] === 'object') {
        for (let pub in testPubs[yr]) {
          pubsByYear.class = `All Years`;
          const doc = document.createElement("div");
          doc.id = testPubs[yr][pub];
          doc.textContent = `${testPubs[yr][pub].author} - ${testPubs[yr][pub].title} - ${pub}`;
          pubsByYear.appendChild(doc);
        }
      }
    }
  }
}
Sign up to request clarification or add additional context in comments.

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.