2

There is an object like this...

{
  2016: {
    3 : [
      { field: "content 1" }
      { field: "content 2" }
    ]
    10 : [
      { field: "content 3" }
    ]
  }
  2017: {
    8 : [
      { field: "content 4" }
    ]
  }
}

...and I need to get access to the subelements in an ascending order. That means I want to process 2016 object first, then 2017 object.

Within that I need to process the month objects also in ascending order.

Iteration like...

for (var year in map) {
    if (map.hasOwnProperty(year)) {
        console.log(year)
    }
}

won't do the job properly.

2
  • There is no order in objects, you'd have to create your own map and follow that. Commented Jul 28, 2017 at 18:19
  • javascript can't sort maps sorry, you're going to have to do something like adding an extra property in you objects like 2016: {year: 2016, ...} then convert the map into an array then sort the array by years Commented Jul 28, 2017 at 18:21

3 Answers 3

2

To get an ordered array of the content, recursively iterate the object, while getting the data by sorted keys, and using Array#concat to flatten the array.

var data = {"2016":{"3":[{"field":"content 1"},{"field":"content 2"}],"10":[{"field":"content 3"}]},"2017":{"8":[{"field":"content 4"}]}};

function iterateByOrder(data) {
  var sorterKeys = Object.keys(data).sort(function(a, b) {
    return a - b; // sort by converting the keys to numbers
  });
  
  return [].concat.apply([], sorterKeys.map(function(key) { // mapping the propeties to values, and flatting sub arrays
    return typeof data[key] === 'object' ? iterateByOrder(data[key]) : data[key];
  }));
}

var result = iterateByOrder(data);

console.log(result);

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

Comments

2

We'll write a little analog of Array#forEach, which iterates over the key/value pairs in an object in sorted order, and calls a function on each pair, passing it the key and its value:

function forEach(object, fn) {
  object.entries() . sort((a, b) => a[0] - b[0]) . forEach(pair => fn(...pair));
}

If you don't have Object#entries, the write it yourself:

function objectEntries(object) {
  return Object.keys(object) . map(key => [key, object[key]]);
}

Now to iterate over your object:

forEach(map, (year, yearValue) => 
  forEach(yearValue, (month, monthValue) => 
    console.log(`At ${year}/${month}, got data ${monthValue}`)));

Comments

0

Javascript objects aren't ordered, so the first thing you will need to do is to grab the keys, sort them, and then iterate in that order.

 data = {
      2016: {
        3 : [
          { field: "content 1" },
          { field: "content 2" },
        ],
        10 : [
          { field: "content 3" },
        ],
      },
      2017: {
        8 : [
          { field: "content 4" },
        ],
      },
    };
    
    var keys = Object.keys(data);
    var sortedKeys = keys.sort(function(a, b) {return parseInt(a) - parseInt(b)});
    
    for (var i = 0; i < sortedKeys.length; i++) {
      var key = sortedKeys[i];
      console.log(data[key]);
    }

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.