Skip to main content
added 122 characters in body
Source Link
le_m
  • 1.9k
  • 10
  • 15

If you combine that with a more descriptive approach by replacing for-loops with forEach and reduce, you get a simpler implementation:

If you combine that with a more descriptive approach by replacing for-loops with reduce, you get a simpler implementation:

If you combine that with a more descriptive approach by replacing for-loops with forEach and reduce, you get a simpler implementation:

added 268 characters in body
Source Link
le_m
  • 1.9k
  • 10
  • 15
function count(a, b) {
  let freqs = {};
  a.split('').forEach(char => freqs[char] = (freqs[char] || 0) + 1); // increment
  b.split('').forEach(char => freqs[char] = (freqs[char] || 0) - 1); // decrement
  return Object.keys(freqs).reduce((sum, key) => sum + Math.abs(freqs[key]), 0);
}

// Count character deletions required to make 'a' and 'b' anagrams:
function count(a, b) {
  let freqs = {};
  a.split('').forEach(char => freqs[char] = (freqs[char] || 0) + 1); // increment
  b.split('').forEach(char => freqs[char] = (freqs[char] || 0) - 1); // decrement
  return Object.keys(freqs).reduce((sum, key) => sum + Math.abs(freqs[key]), 0);
}

// Example:
console.log(count('ilovea', 'challenge')); // 9

function count(a, b) {
  let freqs = {};
  a.split('').forEach(char => freqs[char] = (freqs[char] || 0) + 1); // increment
  b.split('').forEach(char => freqs[char] = (freqs[char] || 0) - 1); // decrement
  return Object.keys(freqs).reduce((sum, key) => sum + Math.abs(freqs[key]), 0);
}

// Count character deletions required to make 'a' and 'b' anagrams:
function count(a, b) {
  let freqs = {};
  a.split('').forEach(char => freqs[char] = (freqs[char] || 0) + 1); // increment
  b.split('').forEach(char => freqs[char] = (freqs[char] || 0) - 1); // decrement
  return Object.keys(freqs).reduce((sum, key) => sum + Math.abs(freqs[key]), 0);
}

// Example:
console.log(count('ilovea', 'challenge')); // 9

Source Link
le_m
  • 1.9k
  • 10
  • 15

I like your idea of counting character frequencies first. This allows you to count the required deletions in linear time.

Your code is readable, but readability can be improved by more semantic naming and leveraging modern JavaScript language features.

###Naming:

Regarding the variable names a, objA, mainObj, resultObj, arrOfAlphabets: Those identifiers mainly include type information (obj, arrOf). But as a reader, I am more interested in the role of your variables instead of their type. So instead of objA I would prefer to read frequenciesA or even freqA. And instead of arrOfAlphabets I suggest the simpler characters.

###For-loops:

First of all, you probably forgot to declare the local loop iterator in for (i = 0; ...). Unfortunately, those omissions can introduce very hard to trace bugs as you now access and potentially share a global variable i.

Also, JavaScript arrays and strings implement the iterable protocoll. This means you can iterate over them using a simpler for-of loop:

for (let char of characters) { ... }

This allows you to replace arrOfAlphabets[i] with the more readable char.

###Default properties: There is a pretty common technique used to handle default values of object properties. Replace

if (obj[arrOfAlphabets[i]]) {
  resultObj[char] += 1;
} else {
  resultObj[char] = 1;
}

with the shorter and idiomatic

resultObj[char] = (resultObj[char] || 0) + 1;

###Enumerate object keys:

Instead of

for (var k in mainObj) {
    if (mainObj.hasOwnProperty(k)) { ... }
}

you can nowadays use Object.keys to write

for (let key of Object.keys(mainObj)) { ... }

###Refactoring:

You probably noticed the redundancy in

var numOfDeletionsA = countNumberOfDeletions(objA,objB);
var numOfDeletionsB = countNumberOfDeletions(objB,objA);
console.log(numOfDeletionsA + numOfDeletionsB);

If you modify your countAlphabetFrequency function to increment frequencies for string a and decrement frequencies for string b, you can simply sum the absolute frequencies to get the number of required deletions.

If you combine that with a more descriptive approach by replacing for-loops with reduce, you get a simpler implementation:

function count(a, b) {
  let freqs = {};
  a.split('').forEach(char => freqs[char] = (freqs[char] || 0) + 1); // increment
  b.split('').forEach(char => freqs[char] = (freqs[char] || 0) - 1); // decrement
  return Object.keys(freqs).reduce((sum, key) => sum + Math.abs(freqs[key]), 0);
}