最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Is it okay to use for in loop on a string? - Stack Overflow

programmeradmin1浏览0评论

Just wondering if its acceptable to use a for in loop on a string. Not sure if there could be weird results or bad practice but my solution works at least in this example.

Coding practice question. Also, if anyone has a way to improve my solution I'm open to advice.

function firstNonRepeatingLetter(str) {
  const lowerStr = str.toLowerCase();

  for (let char in lowerStr) {
    if (lowerStr.lastIndexOf(lowerStr[char]) === parseInt(char) && 
    lowerStr.indexOf(lowerStr[char]) === parseInt(char)) {
      return str[char];
    }
  }

  return "";
}

Write a function named first_non_repeating_letter that takes a string input, and returns the first character that is not repeated anywhere in the string.

Examples:

firstNonRepeatingLetter('a') => 'a'
firstNonRepeatingLetter('stress') => 't'
firstNonRepeatingLetter('sTreSS') => 'T'

Just wondering if its acceptable to use a for in loop on a string. Not sure if there could be weird results or bad practice but my solution works at least in this example.

Coding practice question. Also, if anyone has a way to improve my solution I'm open to advice.

function firstNonRepeatingLetter(str) {
  const lowerStr = str.toLowerCase();

  for (let char in lowerStr) {
    if (lowerStr.lastIndexOf(lowerStr[char]) === parseInt(char) && 
    lowerStr.indexOf(lowerStr[char]) === parseInt(char)) {
      return str[char];
    }
  }

  return "";
}

Write a function named first_non_repeating_letter that takes a string input, and returns the first character that is not repeated anywhere in the string.

Examples:

firstNonRepeatingLetter('a') => 'a'
firstNonRepeatingLetter('stress') => 't'
firstNonRepeatingLetter('sTreSS') => 'T'
Share Improve this question edited Sep 26, 2019 at 21:36 Das_Geek 2,8357 gold badges22 silver badges27 bronze badges asked Sep 26, 2019 at 20:37 Joe SpinelliJoe Spinelli 1052 silver badges11 bronze badges 1
  • Possible duplicate of What's the difference between a string and an array of characters in Javascript? – PM 77-1 Commented Sep 26, 2019 at 20:41
Add a ment  | 

6 Answers 6

Reset to default 4

While your code is working, I suggest to take an index for iterating the characters of a string.

But your approach iterates the string to much by using indexOf and lastIndexOf. This could be changed by using a loop storing the last found index of the character.

In another loop, pare the actual index with the stored one for the same character and return if equal.

function firstNonRepeatingLetter(str) {
    var lowerStr = str.toLowerCase(),
        hash = {},
        i;

    for (i = 0; i < lowerStr.length; i++)
        hash[lowerStr[i]] = i;

    for (i = 0; i < lowerStr.length; i++)
        if (hash[lowerStr[i]] === i)
            return str[i];

    return "";
}

console.log(firstNonRepeatingLetter('a'));      // a
console.log(firstNonRepeatingLetter('stress')); // t
console.log(firstNonRepeatingLetter('sTreSS')); // T

To answer the question, yes, you can use for..in with strings. The truth is, in most cases, you shouldn't.

for(i in X) works this way:

  • if X is not an object, convert it to a respective wrapper (a number to a Number, a string to a String)
  • for each "enumerable property" of X, assign its name to i and run the loop body

So strings are converted to String objects, and, as you can see in the console, they are just like arrays: they have numeric properties from 0 to length - 1 and each property contains the respective character:

That is, yes, the above logic works just fine with strings.

However, if you only want to iterate a string char-by-char, there's a more direct way to do the same: the for..of loop.

for(a of X) picks each element (not property) from X (which can be a string, an array or any "iterable" object) and assigns it to "a". With for..of, your code can be refactored like this:

function firstNonRepeatingLetter(str) {
    const lowerStr = str.toLowerCase();

    for (let char of lowerStr) {
        if (lowerStr.lastIndexOf(char) === lowerStr.indexOf(char))
            return char;
    }

    return "";
}

An algorithmic approach using javascript maps: And yes, it's perfectly fine to use for loops with strings.

const fn = (str) => {
  res = [];
  var ch = new Map();
  for(var i = 0; i<str.length; i++) {
    if(ch.has(str[i])) {
      var val = ch.get(str[i])
      val += 1
      ch.set(str[i],val)
    } else {
      ch.set(str[i], 1)
    }
  }
  ch.forEach((val, key) => {
    if(val == 1) {
      res.push(key)
    }
  })
  return res[0]
}

console.log(fn('abcdeabcdef'))

How about using two array ? Firstly, you can make an array using split and also create reversed array.

const origin = str.split('');
const reverse = [...origin].reverse();

Then, you can use filter.

const nonRepeats = origin.filter((ele, index) => ele !== reverse[index]);
return nonRepeats[0];

To answer the question in the title, the for..in statement is intended for iterating enumerable object properties (including members in the prototype chain). While it "works" on iterable types, it is generally advised against using it as a method of iterating array-like structures as it can yield unexpected results when you are typically only looking at numerical indices.

For example, imagine you later polyfill functionality or otherwise modify the String prototype.

String.prototype.polyfill = () => {}
for(const prop in 'abc')
    console.log(prop)


Edit: Oh snap. Looks like two of us got there at the same time. I'll also note then that regular expressions are good at solving this kind of problem. regex 101

const firstNonRepeatingLetter = str => 
    (str && /(.)(?!.*?\1)/i.exec(str)[0]) || ''
    
;[
    'a',
    'stress',
    'sTreSS'
]
    .forEach(
        str => console.log(firstNonRepeatingLetter(str))
    )

I think once you resolve the answer on a website where you have found this task it will show you other answers, so you can see some other approaches.

Back to the question - you can convert string to array via .split() method. Array provides number of useful methods like .filter(), .map() etc. that can be used instead of for loop.

发布评论

评论列表(0)

  1. 暂无评论