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

javascript - Call join() on a generator in JS - Stack Overflow

programmeradmin6浏览0评论

In Python, you can call the string.join() method on any iterable, like so:

",".join(some_iterable)

The argument may be a list, generator, or any other object as long as it is iterable.

Playing around with ES6, I couldn't find a way to do so without having to create an array first, I had to do something like this:

function *myGenerator() { ... }
let output = [...myGenerator()].join(",");

I know that join() is an Array.prototype method. Is it possible for me to call join() or some equivalent to concatenate the values generated by myGenerator without having to create an intermediate array, like the python example above?

In Python, you can call the string.join() method on any iterable, like so:

",".join(some_iterable)

The argument may be a list, generator, or any other object as long as it is iterable.

Playing around with ES6, I couldn't find a way to do so without having to create an array first, I had to do something like this:

function *myGenerator() { ... }
let output = [...myGenerator()].join(",");

I know that join() is an Array.prototype method. Is it possible for me to call join() or some equivalent to concatenate the values generated by myGenerator without having to create an intermediate array, like the python example above?

Share Improve this question edited Jul 9, 2018 at 22:55 Nasser Al-Shawwa asked Jul 9, 2018 at 22:52 Nasser Al-ShawwaNasser Al-Shawwa 3,67320 silver badges27 bronze badges 9
  • 2 You can just add a function that implements that to String.prototype as join, if you want to; then you could call ','.join(myGenerator()). But you'll at some point either have to create an array to use that join method, or write your own equivalent. And under the hood, I believe the CPython equivalent does create an intermediate array, as that's more efficient than creating lots of intermediate strings instead. – jonrsharpe Commented Jul 9, 2018 at 22:54
  • @jonrsharpe I believe that, in theory, you don't need an intermediate array. If what I'm asking is not achievable at present, then this seems like an overlooked feature of the generators implementation, no? – Nasser Al-Shawwa Commented Jul 9, 2018 at 23:01
  • 1 No, you don't need the array, you could perfectly well write a function that just consumes the iterator and builds the equivalent string. But that builds lots of intermediate strings instead, which is likely less efficient overall. And either way, if that's what you want to write, what is stopping you writing it? – jonrsharpe Commented Jul 9, 2018 at 23:02
  • An answer to your literal question and not the spirit of your question is, you could have a function that takes an iterator, iterates over it, concatenating with a string while adding separators. – CertainPerformance Commented Jul 9, 2018 at 23:03
  • 2 @jonrsharpe You're right, nothing is stopping me from writing it myself, I'm just curious to know if there's an ES6 feature that allows me to join on generators just like I can with Array.prototype.join(). – Nasser Al-Shawwa Commented Jul 9, 2018 at 23:08
 |  Show 4 more ments

1 Answer 1

Reset to default 7

The ments above answer your question pretty well. However, I was curious about @jonrsharpe's ment about generating intermediate strings and was wondering how that actually affected performance. So I put a join method on the prototype of a generator and tested it.

Here's the join() code:

function* nGen(start, stop) {
  while (start < stop) {
    yield start
    start++
  }
}

nGen.prototype.join = function(sep) {
  let res = this.next().value
  for (let v = this.next(); !v.done; v = this.next()) {
    res += sep + v.value
  }
  return res
}


let g = nGen(2, 20)

console.log(g.join(','))

The original jsPerf tests in Safari and Chrome showed this working faster than the very mon idiom: [...g].join(','). In a JSBench test in 2022, results were inconsistent between Chrome, Firefox, and Edge, but this method is now slower than [...g].join(',') and/or a for loop.

I am far from a master of writing jsPerf/JSBench tests, so maybe I'm screwing something up or misinterpreting the result. But if you're interested: https://jsbench.me/zlkz8tm6vw/1

发布评论

评论列表(0)

  1. 暂无评论