11

There is a nested object like that:

var conversation = {
    'John': {
        1: 'Test message 1',
        2: 'Test message 2',
        'Reply': {
            3: 'Test message 3',
            4: 'Test message 4'
        }
    },
    'Jack': {
        5: 'Test message 5',
        6: 'Test message 6'
    }
};

I need to get all final values, so for that example, it is:

Test message 1
Test message 2
Test message 3
Test message 4
Test message 5
Test message 6

How to iterate over the object? Is there any built-in function in jQuery or JavaScript?

Andy
  • 61,948
  • 13
  • 68
  • 95
mrdaliri
  • 7,148
  • 22
  • 73
  • 107
  • possible duplicate of [Dynamically display JSON file contents](http://stackoverflow.com/questions/29478005/dynamically-display-json-file-contents) – renakre Apr 08 '15 at 13:36
  • 7
    You could use You could use You could use recursion recursion recursion. – Rory McCrossan Apr 08 '15 at 13:36

3 Answers3

30

You can use some recursion to check to see if the key being iterated over is an object or not, then print:

function printValues(obj) {
    for (var key in obj) {
        if (typeof obj[key] === "object") {
            printValues(obj[key]);   
        } else {
            console.log(obj[key]);    
        }
    }
}

printValues(conversation);

Demo: http://jsfiddle.net/c7th1t8r/

tymeJV
  • 103,943
  • 14
  • 161
  • 157
  • 4
    If you just want to print, wouldn't you just use `JSON.stringify()`? – Ruan Mendes Apr 08 '15 at 13:37
  • 5
    @JuanMendes -- Why would you use that to print? That'll stringify the object...I think OP wants the values of each key. – tymeJV Apr 08 '15 at 13:38
  • 1
    if you want to make it shorter replace `if` and `else` statments with: `(obj[key].constructor === Object) ? printValues(obj[key]) : console.log(obj[key]);` I changed it to `.constructor === Object` because `typeof []` is also returns `object` – Edwin Reynoso Apr 08 '15 at 13:45
  • 1
    I would add a first condition checking if the object has the specified property: `if(obj.hasOwnProperty(key)){` – andybeli Apr 08 '15 at 13:47
  • 1
    @JuanMendes: `JSON.stringify()` returns keys also, but I need only the values. – mrdaliri Apr 08 '15 at 13:53
3

jQuery has the each function which you could use, in addition to a bit of a recursion to plumb down into your object until you reach something you can print.

var conversation = {
  'John': {
    1: 'Test message 1',
    2: 'Test message 2',
    'Reply': {
      3: 'Test message 3',
      4: 'Test message 4'
    }
  },
  'Jack': {
    5: 'Test message 5',
    6: 'Test message 6'
  }
};

function iterate(obj) {
  if (typeof obj === 'string') {
    $('#log').append((obj + '<br/>'));
  }
  if (typeof obj === 'object') {
    $.each(obj, function(key, value) {
      iterate(value);
    });
  }
}

iterate(conversation);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="log"></div>
Joey Ciechanowicz
  • 3,345
  • 3
  • 24
  • 48
3

A more functional way :

const getObjectValues = (obj) => (obj && typeof obj === 'object')
 ? Object.values(obj).map(getObjectValues).flat()
 : [obj]

This returns an array that can then be printed :

console.log(getObjectValues(conversation))
// ["Test message 1", "Test message 2", "Test message 3", "Test message 4", "Test message 5", "Test message 6"]

EDIT:

If Array.flat is not available in your context, it can be written this way :

const getObjValues = (obj) => (obj && typeof obj === 'object')
  ? Object
    .values(obj)
    .map(getObjValues)
    .reduce((a, b) => a.concat(b), [])
  : [obj]
Jalil
  • 3,150
  • 3
  • 30
  • 39