Home > Software design >  Return true if the string in the first element of the array contains all of the letters of the strin
Return true if the string in the first element of the array contains all of the letters of the strin

Time:05-16

I tried to do this by resetting loop going trough firstword every time its letter matches with secondword letter.

function mutation(arr) { 
  var compare = [];
  var firstword = arr[0].toLowerCase();
  var secondword = arr[1].toLowerCase();
  var j = 0;
  for (let i = 0; i < firstword.length; i  ) {

      if (firstword[i] === secondword[j]) {
      compare.push(secondword[i]);
      i = -1;
      j  ;

      
      
      
    }
  }
  let result = compare.join("")
  if (result.length === secondword.length) {
    return true;
    
  } else {
    return false;
  }
}

console.log(mutation(["Noel", "Ole"])); 

It works in some cases but in others, like above example, it doesn't. What seems to be the problem?

CodePudding user response:

You need to compare.push(secondword[j]) instead of compare.push(secondword[i])

function mutation(arr) {
  var compare = [];
  var firstword = arr[0].toLowerCase();
  var secondword = arr[1].toLowerCase();
  var j = 0;
  for (let i = 0; i < firstword.length; i  ) {
    if (firstword[i] === secondword[j]) {
      compare.push(secondword[j]); // Correction here
      i = -1;
      j  ;
    }
  }
  let result = compare.join("");
  if (result.length === secondword.length) {
    return true;
  } else {
    return false;
  }
}

console.log(mutation(["Noel", "Ole"]));

Also, you can consider using Array.prototype.every.

const mutation = ([first, sec]) => {
  const lowerCaseFirst = first.toLowerCase();
  const lowerCaseSec = sec.toLowerCase();
  return Array.from(lowerCaseSec).every((ch) => lowerCaseFirst.includes(ch));
};

console.log(mutation(["Noel", "Ole"]));

If the strings are small then String.prototype.includes works fine but if they are large then you should consider using a Set.

const mutation = ([first, sec]) => {
  const firstSet = new Set(first.toLowerCase());
  const lowerCaseSec = sec.toLowerCase();
  return Array.from(lowerCaseSec).every((ch) => firstSet.has(ch));
};

console.log(mutation(["Noel", "Ole"]));

CodePudding user response:

Simple ES6 Function, we check with .every() if every characters of secondword is includes inside firstword. It return true if it does.

function mutation(arr) {
          const firstword = arr[0].toLowerCase();
          const secondword = arr[1].toLowerCase();
          return secondword.split('').every(char => firstword.includes(char));
}

console.log(mutation(["Noel", "Ole"]));

CodePudding user response:

The use of Set in SSM's answer works if you don't need to account for duplicate characters in the second string. If you do, here's an implementation that uses a Map of character counts. The map key is the character from string 1 and the value is the number of occurrences. For instance, if you want ["Noel", "Ole"] to return true, but ["Noel", "Olle"] to return false (string 1 does not contain 2 "l" characters). String 2 is then iterated through and character counts decremented if they exist. As soon as a character is not present or the count falls below 1 in the map, the function returns false.

function mutation(arr: string[]): boolean {
    return s1ContainsAllCharsInS2(arr[0].toLowerCase(), arr[1].toLowerCase());
}

function s1ContainsAllCharsInS2(s1: string, s2: string): boolean {
    if (s2.length > s1.length) {
        return false;
    }
    let charCountMap: Map<string, number> = new Map<string, number>();
    Array.from(s1).forEach(c => {
        let currentCharCount: number = charCountMap.get(c);
        charCountMap.set(c, 1   (currentCharCount ? currentCharCount : 0));
    });
    return !Array.from(s2).some(c => {
        let currentCharCount: number = charCountMap.get(c);
        if (!currentCharCount || currentCharCount < 1){
            return true;
        }
        charCountMap.set(c, currentCharCount - 1);
    });
}

CodePudding user response:

A different approach.

Mapping the characters and comparing against that map.

function mutation(arr) {
  const chars = {};

  for (let char of arr[0].toLowerCase()) {
    chars[char] = true;
  }

  for (let char of arr[1].toLowerCase()) {
    if (!chars[char]) {
      return false;
    }
  }

  return true;
}

console.log(mutation(["Noel", "Ole"]));
console.log(mutation(["Noel", "Oleeeeeeeeeeeee"]));

If the count also matters (your code doesn't take it into account) you can count the number of occurrences of each character and comparing these counts.

function mutation(arr) {
  const chars = {};

  for (let char of arr[0].toLowerCase()) {
    chars[char] = (chars[char] || 0)   1;
  }

  for (let char of arr[1].toLowerCase()) {
    // check if chars[char] contains a (not empty == positive) count
    // then decrement it for future checks
    if (!chars[char]--) {
      return false;
    }
  }

  return true;
}

console.log(mutation(["Noel", "Ole"]));
console.log(mutation(["Noel", "Oleeeeeeeeeeeee"]));

  • Related