-2

I have a JSON file and I want to use javascript/jQuery to count its contents and list the results.

Here's the initial code:

var globalJsonVar;
$.getJSON("index.json", function(json) {
  globalJsonVar = json;

  /* Having fetched the json, search and index type:keyword */
  var types = {};
  json.forEach(function(item) {
    if (!types[item.keyword]) {
      types[item.keyword] = 0;
    }
    types[item.keyword]++;
    $('#menu').text(JSON.stringify(types));
  });
});
  • Q1: How do I pass it to html?
  • Q2: Can I split the "keyword" field to an array and count what's inside it as discrete entries? This is the JSON file.

Update Q1 is already fixed here: https://jsfiddle.net/5089L59x/4/

east1999
  • 199
  • 5
  • 15
  • 3
    [Once again](https://stackoverflow.com/questions/48520583/counting-json-ocurrences-with-a-library#comment84036252_48520583) your question is very unclear. Please read and understand [How do I ask a good question?](https://stackoverflow.com/help/how-to-ask) – Liam Jan 30 '18 at 15:52
  • `I want each key and value in the same li and the value to be inside a span so I can style it.` is that not the target? – messerbill Jan 30 '18 at 15:53
  • 2
    I tried to add the fiddle into the question but the fiddle has different code to that in the question so I don't know which one is relevant. – Liam Jan 30 '18 at 15:56
  • i guess the code is different to make it running on `jsfiddle`, but yea this is confusing – messerbill Jan 30 '18 at 16:09
  • Thanks for your corrections @liam. I'm trying to boil down the problem to the simplest question, but I'm still not there yet. – east1999 Jan 30 '18 at 16:31

2 Answers2

1

you are searching for for...in loop:

var keyValues = [];

json.forEach(function(item){
if(!types[item.keyword]){types[item.keyword] = 0;}
    types[item.keyword]++
})
for (var attr in types) {
    console.log(attr)
    console.log(types[attr])
    $('#menu ul').append("<li>"+types[attr]+" <span>"+attr+"</span></li>")
    keyValues.push({key: types[attr], value: [attr]})
  }
console.log(keyValues)

html:

<div id="menu">
  <ul>

  </ul>
</div>

updated fiddle: https://jsfiddle.net/k8xn0n5v/6/

further reading: https://developer.mozilla.org/de/docs/Web/JavaScript/Reference/Statements/for...in

greetings

messerbill
  • 5,499
  • 1
  • 27
  • 38
  • Thank you so much! That works perfectly for the second part of the question, or for a string, but I also want to split it, so I can count and list the full scope of keywords. – east1999 Jan 30 '18 at 15:56
  • will modify it, just wait a moment – messerbill Jan 30 '18 at 15:58
  • [Que another long and tedious exchange in comments..](https://stackoverflow.com/questions/48520583/counting-json-ocurrences-with-a-library#comment84037049_48520583) if you get your question right first then it makes everyone's life easier moving forward @east1999 – Liam Jan 30 '18 at 15:59
  • is this what you are searching for @east1999 ? – messerbill Jan 30 '18 at 16:03
  • Sorry, this doesn't work. If you look at the output from your fiddle, it has more lines than the JSON file, so it's actually repeating them for some reason. – east1999 Jan 30 '18 at 16:30
  • I forked your fiddle here: https://jsfiddle.net/mkkoo2gj/ adding a new field to the JSON, which has only one value per key, and the output still doesn't seem right. – east1999 Jan 30 '18 at 16:30
  • 1
    sorry, i updated my fiddle. it was my bad, my loop was wrongly placed :/ check it out: https://jsfiddle.net/k8xn0n5v/6/ – messerbill Jan 30 '18 at 17:00
  • Yes, thank you @messerbill! It works very much like the fiddle I added in the post update. Two remaining qs: how to split the string so I can count _each_ keyword, and how to sort the result alphabetically – east1999 Jan 30 '18 at 17:08
  • have a look here maybe u can get it from there on: https://jsfiddle.net/k8xn0n5v/7/ - i will return home now, once arrived i will have a look at this post. Have no more time right now ;) – messerbill Jan 30 '18 at 17:19
  • Like I said in the comment to Belian's answer, it doesn't work in the fiddle. It's still the same list of counted strings. – east1999 Jan 31 '18 at 15:18
  • so i really dont get what you ant to achieve, sorry – messerbill Jan 31 '18 at 15:36
  • Let me just clarify: this code allows for counting the number of "keyword" strings. What I want is to split the string to an array, and count the values inside, i.e., a list with X Balloons, X Dogs, etc. Again, thank you for you contribution and your patience. – east1999 Jan 31 '18 at 15:57
  • ok i can do this, but you already marked Beilan's answer solving the issue - so is your problem fixed yet or not? – messerbill Jan 31 '18 at 17:46
1

Answer for Q1: Basically all you have to do is to use the (for .. in .. ) loop to use all properties of an object. (the types object in this case)

var JsonVar;
$.getJSON("https://api.myjson.com/bins/1ba5at", function(jsonData) {
  var types = {};
  jsonData.forEach(function(item) {
    if (!types[item.keyword]) {
      types[item.keyword] = 0;
    }
    types[item.keyword]++;
  });

  for (var typeKey in types) {
    var newLiElement = document.createElement("li");
    var valueSpanElement = document.createElement("span");
    var valueTextNode = document.createTextNode(typeKey.toString());
    var keyTextNode = document.createTextNode("keyword: ");
    var countSpanElement = document.createElement("span");
    var countSpanText = document.createTextNode(types[typeKey].toString());

    //here you can style the keys
    valueSpanElement.setAttribute("style", "background-color: blue; color: white;");
    countSpanElement.setAttribute("style", "margin-left: 10px; background-color: black; color: white; text-weight: bold;");

    countSpanElement.appendChild(countSpanText);

    valueSpanElement.appendChild(valueTextNode);

    newLiElement.appendChild(keyTextNode);
    newLiElement.appendChild(valueSpanElement);
    newLiElement.appendChild(countSpanElement);


    document.getElementById("menu").appendChild(newLiElement);
  }
});

Here is the fiddle link: https://jsfiddle.net/k8xn0n5v/5/

Answer for Q2: All you have to do is to create an array from the string keywords using the string.split() method. (in this case, the ', ' argument will work fine)

I have updated the fiddle, now you can find the keyword:count values in an array.

https://jsfiddle.net/5089L59x/15/

Extending the code of your fiddle looks like this:

var JsonVar;
$.getJSON("https://api.myjson.com/bins/lz839", function(jsonData) {
  var types = {};
  jsonData.forEach(function(item) {
    if (!types[item.keyword]) {
      types[item.keyword] = 0;
    }
    types[item.keyword]++;
  });

  var keywordsCountObject = {};
  for (var typeKey in types) {
    var keywordItemsToCount = typeKey.toString().split(", ");

    keywordItemsToCount.forEach(function(itemToCount) {
      console.log(itemToCount);
      if (!keywordsCountObject.hasOwnProperty(itemToCount)) {
        keywordsCountObject[itemToCount] = 1;
      } else {
        keywordsCountObject[itemToCount]++;
      }
    });
  }

  for (var prop in keywordsCountObject) {
    $("ul#menu").append("<li>" + prop + " " + keywordsCountObject[prop].toString() + "</li>");
  }

});
Belian
  • 114
  • 8
  • This works like a charm. My problem was getting the for loop right. I replaced everything in the brackets for `$("#menu ul").append("
  • " + typeKey.toString() + types[typeKey].toString() + "
  • ")` — it's easier if I use jQuery. – east1999 Jan 30 '18 at 16:39
  • I just noticed your edit and I think I get the principle of using `split()` but it doesn't work in the fiddle. Still a list of counted _strings_, not the discrete entries within the strings. Perhaps the split needs to come first, then the count? – east1999 Jan 31 '18 at 15:17
  • 1
    Okay, wait a few mins, i take a look. :) – Belian Jan 31 '18 at 15:18
  • Okay, so you can find the extracted keywords in the keywordArray variable. Check this fiddle: https://jsfiddle.net/5089L59x/8/ Is this what you are looking for? – Belian Jan 31 '18 at 15:23
  • I'm sorry, but I don't think so. The output I'm seeking would be like `Bubbles: 3, Computers: 3, Dogs: 3, Yellow: 1` (etc). – east1999 Jan 31 '18 at 15:28
  • Oh. Okay, wait a few mins im on it. – Belian Jan 31 '18 at 15:29
  • I updated the Q2 section of my answer. Check it out! – Belian Jan 31 '18 at 15:55
  • That is perfect and I'm marking the question as solved! Thank you so so much. I'm only adding one more thing, but it's outside the scope of what I asked before: is there a way to sort the result alphabetically? – east1999 Jan 31 '18 at 16:01
  • 1
    Thanks :) Happy to help you. I think here you can find answer to your question: https://stackoverflow.com/questions/1359761/sorting-a-javascript-object-by-property-name – Belian Jan 31 '18 at 16:19
  • That was a precious clue and I ended up finding a jQuery answer for that, sorting the DOM elements and not the JSON itself — see here https://codepen.io/gabrieleromanato/pen/Cfpdu and a working fiddle here https://jsfiddle.net/psw1p5p2/2/ – east1999 Feb 01 '18 at 12:13