skip to Main Content

The Output should be only: rabbit and bibe but im getting it wrong all in the list is printing because last index has ‘b’ as well how can i print the specified element that contain only ‘bib’

let str = 'bib'
let list = ['rabbit', 'bibe', 'bundle']
for (let i = 0; i < list.length; i++) {
  for (let j = 0; j < list[i].length; j++) {
    let foundIndex = str.indexOf(list[i][j]) > -1
    if (foundIndex === -1) {
      list.splice(foundIndex, 1)
    } else if (foundIndex) {
      console.log(list[i])
    }
  }
}

Expecting Output should be:

rabbit
bibe

3

Answers


  1. A simple solution would be counting the number of each unique character in the given string and then filter the elements base on that: If an element has all of those characters, each with the same or higher amount, then it should be kept.

    First, declare a helper function:

    function stringToMap(string) {
      return [...string].reduce((map, char) => {
        map[char] = map[char] + 1 || 1;
        return map;
      }, {});
    }
    

    It will return an object that looks like this:

    {
      b: 2,
      i: 1
    }
    

    Array objects have a very convenient method named .every() which returns true if and only if the callback function returns true for all elements. We want to make use of it, so we convert the object above to an array of key-value pairs using Object.entries():

    const charsAndAmount = Object.entries(stringToMap(str));
    
    // The object above now looks like this:
    [
      ['b', 2],
      ['i', 1]
    ]
    

    We do the same for each element of the list (not the Object.entries() part; we don’t need their .every()):

    const charMaps = list.map(stringToMap);
    
    [
      { r: 1, a: 1, b: 2, i: 1, t: 1 },
      { b: 2, i: 1, e: 1 },
      { b: 1, i: 1, k: 1, e: 1 },
      { b: 1, u: 1, n: 1, d: 1, l: 1, e: 1 }
    ]
    

    This is the tricky part: For every word in the list, we check if it contains every character in the given string, each with the same or higher amount. If it does, .every() will return true and .filter() will keep the word in the new list:

    const output = list.filter(
      (_, index) => charsAndAmount.every(
        ([char, number]) => number <= charMaps[index][char]
      // [ 'b',      2]       2    <=
      //           ({ r: 1, a: 1, b: 2, i: 1, t: 1 })['b']
      // 2 <= 2 === true
      )
    );
    

    Try it:

    function stringToMap(string) {
      return [...string].reduce((map, char) => {
        map[char] = map[char] + 1 || 1;
        return map;
      }, {});
    }
    
    const str = 'bib';
    
    const charsAndAmount = Object.entries(stringToMap(str));
    
    const list = ['rabbit', 'bibe', 'bike', 'bundle'];
    
    const charMaps = list.map(stringToMap);
    
    const output = list.filter(
      (_, index) => charsAndAmount.every(
        ([char, number]) => number <= charMaps[index][char]
      )
    );
    
    console.log(output);
    Login or Signup to reply.
  2. You can simply achieve this with the help of Array.every() method which tests whether all elements in the array pass the test implemented by the provided function. It returns a Boolean value.

    Live Demo :

    let str = 'bib'
    let list = ['rabbit','bibe','bundle']
    for(let i = 0; i < list.length; i++) {
      const allMatched = str.split('').every(e => list[i].indexOf(e) !== -1);
      if (allMatched) {
        console.log(list[i]);
      }
    }

    Updated answer as per the author comment :

    let str = 'bib';
    let list = ['rabbit','bibe','bundle'];
    
    const res = list.map(e => {
        return e.split('').filter(c => str.includes(c)).join('').length
    });
    
    res.forEach((matchedLength, index) => {
        if (matchedLength >= 3) {
        console.log(list[index])
      }
    })
    Login or Signup to reply.
  3. Here’s another solution, if we sort the letters "bib" becomes "bbi".

    If we do a similar thing with the list ["rabbit","bibe","bundle"] becomes ["abbirt", "bbei" and "bdelnu"]. If we filter the letters not in "bib" the list shrinks to ["bbi","bbi","b"]. What we can now do is check for the occurrences of "bbi" in the resultant list.

    Here’s an intermediate implementation of the above:

    let str = 'bib';
    let list = ['rabbit','bibe','bundle'];
    let str2 = [...str].sort().join('');
    let result =list.filter( function (w) {
        let w2 = [...w].filter( c => str.indexOf(c) !== -1 ).sort().join('');
        return w2.indexOf(str2) !== -1;
    } );
    console.log(JSON.stringify(result));

    Here’s the same code but golfed some more:

    let str = 'bib';
    let list = ['rabbit','bibe','bundle'];
    let result = list.filter( w => [...w].filter( c => str.indexOf(c) !== -1 ).sort().join('').indexOf([...str].sort().join('')) !== -1);
    console.log(JSON.stringify(result));
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search