Search code examples
javascriptarraysnestedcomparison

How to solve this js nested arrays problems: given a word and an array of string skeletons return an array of possible skeleton-word matches


after working at this for many hours, I am lost at how to solve the following problem. Please offer solutions with explanations or suggestions to improve my solution.

/* instructions
Given a word and an array of string skeletons, return an array of all of the skeletons that could be turned into the word by replacing the '-' with letters. If there are no possible matches return an empty string example: given the word 'hello' 'he---' would 
be a match, 'h--l' or 'g-llo' would not be a match */

// example test case:
let word = 'hello';
let skeletons = ['h--l', 'he---', 'g-llo', 'm-llo', '--llo', 'h-l--'];

function findSkels(word, skeleton){
let goodSkels = [];
skeleton = skeletons.filter(w => w.length === word.length);
console.log(skeletons)
  for(let sw = 0; sw < skeletons.length; sw++){
    let possibleMatch = true;
    for(let letter = 0; letter < word.length; letter++){
      if(word[letter] !== skeletons[sw][letter] || skeletons[sw][letter] == '-'){
        possibleMatch = false
      }
    }
    if(possibleMatch){
      goodSkels.push(skeletons[sw])
    }
  } 
    return goodSkels;
}


Solution

  • You're close, but

    if (word[letter] !== skeletons[sw][letter] || skeletons[sw][letter] == '-') {
      possibleMatch = false
    }
    

    will disqualify a skeleton if any letter doesn't match or the letter is a -. So this'll disqualify any words that aren't exact matches. You want && instead - disqualify only if the letter doesn't match and the letter isn't a -.

    /* instructions
    Given a word and an array of string skeletons, return an array of all of the skeletons that could be turned into the word by replacing the '-' with letters. If there are no possible matches return an empty string example: given the word 'hello' 'he---' would 
    be a match, 'h--l' or 'g-llo' would not be a match */
    
    // example test case:
    let word = 'hello';
    let skeletons = ['h--l', 'he---', 'g-llo', 'm-llo', '--llo', 'h-l--'];
    
    function findSkels(word, skeleton) {
      let goodSkels = [];
      skeleton = skeletons.filter(w => w.length === word.length);
      for (let sw = 0; sw < skeletons.length; sw++) {
        let possibleMatch = true;
        for (let letter = 0; letter < word.length; letter++) {
          if (word[letter] !== skeletons[sw][letter] && skeletons[sw][letter] !== '-') {
            possibleMatch = false
          }
        }
        if (possibleMatch) {
          goodSkels.push(skeletons[sw])
        }
      }
      return goodSkels;
    }
    console.log(findSkels(word, skeletons));

    Or, refactored to look nicer:

    const word = 'hello';
    const skeletons = ['h--l', 'he---', 'g-llo', 'm-llo', '--llo', 'h-l--'];
    
    const findSkels = (word, skeletons) => skeletons
      .filter(skel => (
        skel.length === word.length &&
        [...skel].every((char, i) => char === '-' || char === word[i])
      ));
    console.log(findSkels(word, skeletons));

    Array methods are often a nice way to make code much cleaner than imperative index-based for loops. If you don't actually care about the index, only the value being iterated over, you can often ditch the for (let i = construct entirely, and either use an array method or for..of.