2

The have this simple function to count letter frequency

function getFreq(str){
  var freq={};
  str.replace(/[a-z A-Z]/g, function(match){
    freq[match] = (freq[match] || 0) + 1;
    return match;
  });
  console.log(JSON.stringify(freq));
  return freq;
  
}
<input type="text" onchange="getFreq(this.value);" />

Input sample : Hello World

Output :

{"H":1,"e":1,"l":3,"o":2," ":1,"W":1,"r":1,"d":1}

Expected Output :

{"d":1,"e":1,"l":3,"o":2,"r":1,"H":1,"W":1," ":1}  

----- lower case , then Upper case, whitespaces at last

I tried using console.log(JSON.stringify(freq.sort())); to sort the result but it didn't worked.

Shivkumar kondi
  • 6,458
  • 9
  • 31
  • 58

3 Answers3

2

There's nothing in your code which is sorting anything. Object properties will be serialized in the order in which they're created (other than things that look like array indexes), as of ES2015, but that's not generally useful. When you want order, use an array. See comments:

// Let's use modern event handling
document.getElementById("btn").addEventListener("click", function() {
  getFreq(document.getElementById("field").value);
}, false);

function getFreq(str){
  var freq={};
  str.replace(/[a-z A-Z]/g, function(match){
    freq[match] = (freq[match] || 0) + 1;
    return match;
  });
  // Build an array with the results in string order by splitting it
  // and then mapping letters to objects with the frequency
  var result = [];
  str.split("").forEach(function(letter) {
    if (freq.hasOwnProperty(letter)) {
      result.push({letter: letter, freq: freq[letter]});
    }
  });
  console.log(result);
}
<input type="text" value="Hello world" id="field">
<input type="button" id="btn" value="Run">

Technically, you could produce the desired output with an object because you're only using single-letter alphabetic strings as keys, and as of ES2015 those will be stringified in the order in which they were added to the object. (JSON.stringify does follow property order as of ES2015.) But it only works because you're ignoring digits; if digits were included, they wouldn't appear in the order you want (the digits would come before the letters, in numeric order).

Purely for academic purposes (requires an ES2015-compliant browser):

// NOT A GOOD IDEA

document.getElementById("btn").addEventListener("click", function() {
  getFreq(document.getElementById("field").value);
}, false);

function getFreq(str){
  var freq={};
  str.replace(/[a-z A-Z]/g, function(match){
    freq[match] = (freq[match] || 0) + 1;
    return match;
  });
  // Build an object with the results in string order by splitting it
  // and then adding properties to an object in order
  var result = {};
  str.split("").forEach(function(letter) {
    result[letter] = freq[letter];
  });
  console.log(JSON.stringify(result));
}
<input type="text" value="Hello world" id="field">
<input type="button" id="btn" value="Run">

But, again, that relies on the assumption you're only using alphabetic characters.

T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
1

You can use Object.keys combined with reduce to do this. The only caveat is that whitespace has and ASCII value of 32. SO it will always be the first character in this sorted list.

Refer: http://www.theasciicode.com.ar/ascii-printable-characters/space-ascii-code-32.html

function getFreq(str){
  var freq={};
  str.replace(/[a-z A-Z]/g, function(match){
    freq[match] = (freq[match] || 0) + 1;
    return match;
  });
  console.log(JSON.stringify(freq));
  
  return Object.keys(freq)
    .sort()
    .reduce((accumulator, k) => {
      accumulator[k] = freq[k]; 
      return accumulator;
    }, {});
  
}

console.log(getFreq("Hello World"));
Shivkumar kondi
  • 6,458
  • 9
  • 31
  • 58
Aditya Singh
  • 15,810
  • 15
  • 45
  • 67
1

You could use a custom sort function for moving all small letters to front and upper case letters in between and space to the end.

function getFreq(str){
    var freq = {}, result;
    str.replace(/[a-z A-Z]/g, function (match) {
        freq[match] = (freq[match] || 0) + 1;
    });
    result = Object.keys(freq).sort(function (a, b) {
        var aa = a.toLowerCase(),
            bb = b.toLowerCase();
        return (a === ' ') - (b === ' ') || (a !== aa) - (b !== bb) || aa.localeCompare(bb);
    }).map(function (k) {
        return { letter: k, count: freq[k] };
    });
    console.log(result);
    return freq;
}
<input type="text" onchange="getFreq(this.value);" />
Nina Scholz
  • 376,160
  • 25
  • 347
  • 392