1

I am trying to achieve the following output but keep coming up short. Not sure I am taking the correct approach on this one. I looking to only allow only letters in the field also.

Html:

<input type="text" id="input-field" onkeyup="myFunction()">

Js:

const remDup= s=> s.split("").filter((e,i,f)=>f.indexOf(e)==i).sort().join("")
const myFunction = (e) => {
  let str = document.getElementById('input-field').value
  //Only allow letters no other characters
  if(("abcdefghijklmnopqrstuvwxyz ").indexOf(String.fromCharCode(e.keyCode))===-1){
    e.preventDefault();
    return false;
  }
  console.log(remDup(str))
}

3 Answers 3

3

The logic will probably be better if you iterate over the string, filtering it by whether the lower-case version of the character being iterated over exists in a Set that you add to on every iteration.

Note that you do need to transform the character to lower-case before you test, which your current code isn't doing (nor does it look to be checking for duplicate characters):

const myFunction = (e) => {
  const input = document.getElementById('input-field').value;
  const alphaInput = input.replace(/[^a-z]/gi, '');
  const haveChars = new Set();
  const outputArr = [...alphaInput].filter((char) => {
    const lower = char.toLowerCase();
    if (haveChars.has(lower)) {
      return false;
    } else {
      haveChars.add(lower);
      return true;
    }
  });
  const strWithoutDupes = outputArr.join('');
  console.log(strWithoutDupes);
}
<input type="text" id="input-field" onkeyup="myFunction()" value="AbraCadABraAlakAzam">

Sign up to request clarification or add additional context in comments.

Comments

1

There's a slightly shorter version that you can write using Set:

const input = document.getElementById('input-field');
input.addEventListener('keyup', handleKeyUp, false);
const re = /[a-zA-Z]/;

function handleKeyUp(e) {

  // `reduce` over the value comparing the current element
  // to a lowercase list of previous iterated letters  
  const deduped = [...e.target.value].reduce((acc, el) => {
    const k = el.toLowerCase();
    if (!re.test(el) || acc.tmp.has(k)) return acc;
    acc.tmp.add(k);
    acc.out.push(el);
    return acc;
  }, { out: [], tmp: new Set() }).out.join('');
  console.log(deduped);
}
<input type="text" id="input-field" value="AbraCadABraAlakAzam">

6 Comments

Letters are still being duplicated - "AbraCdBlkzm"
It just verifies lowercase letters now. @user992731. I assume that's what you mean.
Upper and lower. Desired output is ""AbrCdlkzm". Big fan of this shorter version
So if there's an uppercase A there shouldn't be a lowercase a.
I only want to keep the first occurrence regardless of case.
|
0

Here is a solution that solves your problem in O(n) time and space.

const removeDups = (léString) => {
  const strArray = léString.split('')
  const charsSeen = {}
  let stripped = ''
  strArray.forEach(char => {
    if (!charsSeen[char.toLowerCase()]) {
      stripped += char
      charsSeen[char.toLowerCase()] = true
    }
  })

    return stripped
  }

  console.log(removeDups('AbraCadABraAlakAzam'))

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.