Looping through JSON


#1

Hey. My question is - I have a JSON file that looks like this:

{
    {
    'quote':'Tears come from the heart and not from the brain',
    'author':'Leonardo da Vinci',
    'mood': 'sad'
},
   {
    'quote':'There’s death all around us. Everywhere we look. 1.8 people kill themselves every second. We just don’t pay attention. Until we do',
    'author': 'Cynthia Hand',
    'mood': 'sad'
}
}

And so on (it’s for Random Quote Machine challenge).
I wanna make two kinds of random choice - fully random (randomly choosing from all quotes) and cathegorically random (choosing from cathegory, i.e. sad). How do I do it? How to interate through JSON?


#2

Is it an array of quotes like (note the square brackets versus curly brackets:

[
    {
      'quote':'Tears come from the heart and not from the brain',
      'author':'Leonardo da Vinci',
      'mood': 'sad'
   },
  {
    'quote':'There’s death all around us. Everywhere we look. 1.8 people kill themselves every second. We just don’t pay attention. Until we do',
    'author': 'Cynthia Hand',
    'mood': 'sad'
  }
]

If it is really is an object of objects, then it would look more like:

{
  "sad": {
    'quote':'Tears come from the heart and not from the brain',
    'author':'Leonardo da Vinci',
   }, 

  "happy": {
    'quote':'Be happy for this moment. This moment is your life.',
    'author':'Omar Khayyam',
   }
};

Let me know which it is, so I can provide the best solution for you.


#3

Hmmm… In fact, it’s a nice question =) I think it’d better to make it an object of objects, but I’m not sure what’s more suitable for the task. What do you think?


#4

You said you had a JSON file that looked a certain way. What creates the JSON file? Is it an API? I would work with whatever the API sends back.


#5

Definitely keep it an array. There are a bunch of methods for arrays that make life easier. This is how I would do it:

var quotes = [
    {
      'quote':'I am chicken!',
      'author':'Me',
      'mood': 'sad'
   },
  {
    'quote':'I am robot!',
    'author': 'Me',
    'mood': 'sad'
  },
  {
    'quote':'I am robot chicken!',
    'author': 'Me',
    'mood': 'happy'
  },
]

// Generate an random value between a min and max value inclusive.
const random = (min, max) => {
  min = Math.ceil(min);
  max = Math.floor(max);
  return Math.floor(Math.random() * (max - min + 1)) + min;
}

/*
 * Filter an array based a prop and a criterion. 
 * Strict equality check should do fine for primitive types.
 */
const filter = (prop, criterion) => {
  return quotes.filter((quote) => quote[prop] === criterion);
}
// Filter only objects with a prop mood that have a value of happy.
var filterByMood = filter('mood', 'happy');
var randomFromFiltered = random(0, filterByMood.length-1);
var randomFromAll = random(0, quotes.length-1);

console.log(filterByMood[randomFromFiltered]);
console.log(quotes[randomFromAll]);

Codepen

Articles that can help:
Math.random()
Array

If you have any question feel free to ask :).


#6

After thinking about, I agree with @nr-mihaylov with having an array of objects.

I simplified his example with the following code. If you call the function with no arguments, it will return a random quote. If you supply a specific property (prop) and a specific value for the property (criterion), then it will return a random quote of that specific property type.

const random = arrLen => Math.floor(Math.random() * arrLen); // assumes zero based array

const getRandomQuote = (...args) => {
  const possibleQuotes = args.length ? quotes.filter(quote => quote[args[0]] === args[1]) : quotes;
  return possibleQuotes[random(possibleQuotes.length)];
};

getRandomQuote();

#7

Thanks a lot! In fact, I have only one question - if there are any good tutorials on arrow notation, could you pls give me one? I really lack knowledge in this area.


#8

Below uses ES6 const, arrow functions, spread operator, and destructuring assignment:

const random = arrLen => Math.floor(Math.random() * arrLen); // assumes zero based array

const getRandomQuote = (...args) => {
  [prop,criterion] = args;
  const possibleQuotes = args.length ? quotes.filter(quote => quote[prop] === criterion) : quotes;
  return possibleQuotes[random(possibleQuotes.length)];
};

Below is the rewrite of the above functions without any ES6 syntax:

var random = function(arrLen) {
  return Math.floor(Math.random() * arrLen); // assumes zero based array
};

var getRandomQuote = function(prop, criterion) {
  var possibleQuotes = arguments.length ? quotes.filter(function(quote) {
    return quote[prop] === criterion;
    }) : quotes;
  return possibleQuotes[random(possibleQuotes.length)];
};