Get loop counter/index using for…of syntax in JavaScript

后端 未结 11 1925
走了就别回头了
走了就别回头了 2020-11-28 00:55

Caution:

question still applies to for…of loops.> Don\'t use for…in to iterate over an Array, use it

相关标签:
11条回答
  • 2020-11-28 01:12

    Answer Given by rushUp Is correct but this will be more convenient

    for (let [index, val] of array.entries() || []) {
       // your code goes here    
    }
    
    0 讨论(0)
  • 2020-11-28 01:15

    In ES6, it is good to use for - of loop. You can get index in for of like this

    for (let [index, val] of array.entries()) {
            // your code goes here    
    }
    

    Note that Array.entries() returns an iterator, which is what allows it to work in the for-of loop; don't confuse this with Object.entries(), which returns an array of key-value pairs.

    0 讨论(0)
  • 2020-11-28 01:17

    That's my version of a composite iterator that yields an index and any passed generator function's value with an example of (slow) prime search:

    const eachWithIndex = (iterable) => {
      return {
        *[Symbol.iterator]() {
          let i = 0
          for(let val of iteratable) {
            i++
              yield [i, val]
          }
        }
      }
    
    }
    
    const isPrime = (n) => {
      for (i = 2; i < Math.floor(Math.sqrt(n) + 1); i++) {
        if (n % i == 0) {
          return false
        }
      }
      return true
    }
    
    let primes = {
      *[Symbol.iterator]() {
        let candidate = 2
        while (true) {
          if (isPrime(candidate)) yield candidate
            candidate++
        }
      }
    }
    
    for (const [i, prime] of eachWithIndex(primes)) {
      console.log(i, prime)
      if (i === 100) break
    }

    0 讨论(0)
  • 2020-11-28 01:21

    On top of the very good answers everyone posted I want to add that the most performant solution is the ES6 entries. It seems contraintuitive for many devs here, so I created this perf benchamrk.

    It's ~6 times faster. Mainly because doesn't need to: a) access the array more than once and, b) cast the index.

    0 讨论(0)
  • 2020-11-28 01:22

    How about this

    let numbers = [1,2,3,4,5]
    numbers.forEach((number, index) => console.log(`${index}:${number}`))
    

    Where array.forEach this method has an index parameter which is the index of the current element being processed in the array.

    0 讨论(0)
  • 2020-11-28 01:22

    Here's a function eachWithIndex that works with anything iterable.

    You could also write a similar function eachWithKey that works with objets using for...in.

    // example generator (returns an iterator that can only be iterated once)
    function* eachFromTo(start, end) { for (let i = start; i <= end; i++) yield i }
    
    // convers an iterable to an array (potential infinite loop)
    function eachToArray(iterable) {
        const result = []
        for (const val of iterable) result.push(val)
        return result
    }
    
    // yields every value and index of an iterable (array, generator, ...)
    function* eachWithIndex(iterable) {
        const shared = new Array(2)
        shared[1] = 0
        for (shared[0] of iterable) {
            yield shared
            shared[1]++
        }
    }
    
    console.log('iterate values and indexes from a generator')
    for (const [val, i] of eachWithIndex(eachFromTo(10, 13))) console.log(val, i)
    
    console.log('create an array')
    const anArray = eachToArray(eachFromTo(10, 13))
    console.log(anArray)
    
    console.log('iterate values and indexes from an array')
    for (const [val, i] of eachWithIndex(anArray)) console.log(val, i)
    

    The good thing with generators is that they are lazy and can take another generator's result as an argument.

    0 讨论(0)
提交回复
热议问题