从数组创建一个迭代器。

huangapple go评论76阅读模式
英文:

Make an iterator from an array

问题

我目前正在修改一些代码,尝试不影响初始<s>结构</s>代码。在数组上有一个for...of循环,并且有第二个具有相同结构的数组,我想知道是否有一种快速的方法可以生成第二个数组的生成器以模拟zip。

这里是一个示例:

const firstArray = [&quot;a&quot;, &quot;b&quot;, &quot;c&quot;];
const myAdditionalArray = [1, 2, 3];
// const generatorOverMyAdditionalAray = ???
for (const item of firstArray) {
  // Initial code doing stuff with item
  const additionalItem = myAdditionalArray.next();  
  // More code doing stuff with item and additionalItem
}

对于Python爱好者,它会看起来像这样

&gt;&gt;&gt; a = [&quot;a&quot;, &quot;b&quot;, &quot;c&quot;]
&gt;&gt;&gt; b = [1, 2, 3]
&gt;&gt;&gt; generator_over_b = (x for x in b)
&gt;&gt;&gt; for item in a:
...     additional_item = next(generator_over_b)
...     print(item, additional_item)
... 
a 1
b 2
c 3

编辑:强调了为什么forforEach循环不是可行解决方案(最终未回答问题)。

英文:

I am currently modifying some code and trying to not mess with the initial <s>structure</s> code. Having a for...of loop over an array, and having a second array with an identical structure, I am wondering if there is a quick way to make a generator over my second array to simulate a zip.

Here's an example:

const firstArray = [&quot;a&quot;, &quot;b&quot;, &quot;c&quot;];
const myAdditionalArray = [1, 2, 3];
// const generatorOverMyAdditionalAray = ???
for (const item of firstArray) {
  // Initial code doing stuff with item
  const additionalItem = myAdditionalArray.next();  
  // More code doing stuff with item and additionalItem
}

For pythonistas, it would look something like that

&gt;&gt;&gt; a = [&quot;a&quot;, &quot;b&quot;, &quot;c&quot;]
&gt;&gt;&gt; b = [1, 2, 3]
&gt;&gt;&gt; generator_over_b = (x for x in b)
&gt;&gt;&gt; for item in a:
...     additional_item = next(generator_over_b)
...     print(item, additional_item)
... 
a 1
b 2
c 3

Edit: Added emphasis on why for or forEach loops are not a viable solution (and ultimately do not answer the question)

答案1

得分: 2

Arrays have a values method for getting an iterator:

const firstArray = ["a", "b", "c"];
const generatorOverMyAdditionalArray = [1, 2, 3].values();
for (const item of firstArray) {
  const additionalItem = generatorOverMyAdditionalArray.next().value;  
  console.log(item, additionalItem);
}

You could also implement a zip-like generator using [Symbol.iterator], which is the method an object should have when it is iterable:

function* zip(...args) {
    const iters = args.map(arg => arg[Symbol.iterator]());
    while (true) {
        const results = iters.map(iter => iter.next());
        if (results.some(({done}) => done)) break;
        yield results.map(({value}) => value);
    }
}

const arg1 = "abc";
const arg2 = [1, 2, 3];
const arg3 = new Set(["X", "Y", "Z"]);
for ([a, b, c] of zip(arg1, arg2, arg3)) {
    console.log(a, b, c);
}
英文:

Arrays have a values method for getting an iterator:

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-js -->

const firstArray = [&quot;a&quot;, &quot;b&quot;, &quot;c&quot;];
const generatorOverMyAdditionalAray = [1, 2, 3].values();
for (const item of firstArray) {
  const additionalItem = generatorOverMyAdditionalAray.next().value;  
  console.log(item, additionalItem);
}

<!-- end snippet -->

You could also implement a zip like generator, using [Symbol.iterator] -- which is the method an object should have when it is iterable:

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-js -->

function* zip(...args) {
    const iters = args.map(arg =&gt; arg[Symbol.iterator]());
    while (true) {
        const results = iters.map(iter =&gt; iter.next());
        if (results.some(({done}) =&gt; done)) break;
        yield results.map(({value}) =&gt; value);
    }
}

const arg1 = &quot;abc&quot;;
const arg2 = [1, 2, 3];
const arg3 = new Set([&quot;X&quot;, &quot;Y&quot;, &quot;Z&quot;]);
for ([a, b, c] of zip(arg1, arg2, arg3)) {
    console.log(a, b, c);
}

<!-- end snippet -->

答案2

得分: 1

Array#values() 提供了一个数组的迭代器:

const firstArray = ["a", "b", "c"];
const myAdditionalArray = [1, 2, 3];

const generatorOverMyAdditionalAray = myAdditionalArray.values();

for (const item of firstArray) {
  // 初始代码处理item
  const additionalItem = generatorOverMyAdditionalAray.next();  
  // 处理item和additionalItem的更多代码
  console.log(item, additionalItem.value);
}

通常,for..of 使用 迭代协议,因此在值上使用它将使用众所周知的 @@iterator 获取一个迭代器。对于数组,该符号被别名为 .value,因此两者是等价的:

const firstArray = ["a", "b", "c"];
const myAdditionalArray = [1, 2, 3];

const generatorOverMyAdditionalAray = myAdditionalArray[Symbol.iterator]();

for (const item of firstArray) {
  // 初始代码处理item
  const additionalItem = generatorOverMyAdditionalAray.next();  
  // 处理item和additionalItem的更多代码
  console.log(item, additionalItem.value);
}

@@iterator 符号可以与任何可迭代对象一起使用,例如,一个集合:

const firstArray = ["a", "b", "c"];
const myAdditionalSet = new Set()
  .add(1)
  .add(2)
  .add(1) // 重复的将会被移除 
  .add(3);

const generatorOverMyAdditionalAray = myAdditionalSet[Symbol.iterator]();

for (const item of firstArray) {
  // 初始代码处理item
  const additionalItem = generatorOverMyAdditionalAray.next();  
  // 处理item和additionalItem的更多代码
  console.log(item, additionalItem.value);
}

或者一个字符串:

const firstArray = ["a", "b", "c"];
const myAdditionalString = "123";

const generatorOverMyAdditionalAray = myAdditionalString[Symbol.iterator]();

for (const item of firstArray) {
  // 初始代码处理item
  const additionalItem = generatorOverMyAdditionalAray.next();  
  // 处理item和additionalItem的更多代码
  console.log(item, additionalItem.value);
}
英文:

Array#values() gives an iterator over an array:

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-js -->

const firstArray = [&quot;a&quot;, &quot;b&quot;, &quot;c&quot;];
const myAdditionalArray = [1, 2, 3];

const generatorOverMyAdditionalAray = myAdditionalArray.values();

for (const item of firstArray) {
  // Initial code doing stuff with item
  const additionalItem = generatorOverMyAdditionalAray.next();  
  // More code doing stuff with item and additionalItem
  console.log(item, additionalItem.value);
}

<!-- end snippet -->

In general, for..of uses the iteration protocol so using it on a value will fetch an iterator using the well-known @@iterator. For arrays, the symbol is aliased to .value, so the two are equivalent:

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-js -->

const firstArray = [&quot;a&quot;, &quot;b&quot;, &quot;c&quot;];
const myAdditionalArray = [1, 2, 3];

const generatorOverMyAdditionalAray = myAdditionalArray[Symbol.iterator]();

for (const item of firstArray) {
  // Initial code doing stuff with item
  const additionalItem = generatorOverMyAdditionalAray.next();  
  // More code doing stuff with item and additionalItem
  console.log(item, additionalItem.value);
}

<!-- end snippet -->

The @@iterator symbol can be used with any iterable, for example, a set:

<!-- begin snippet: js hide: true console: true babel: false -->

<!-- language: lang-js -->

const firstArray = [&quot;a&quot;, &quot;b&quot;, &quot;c&quot;];
const myAdditionalSet = new Set()
  .add(1)
  .add(2)
  .add(1) //duplicate will be removed 
  .add(3);

const generatorOverMyAdditionalAray = myAdditionalSet[Symbol.iterator]();

for (const item of firstArray) {
  // Initial code doing stuff with item
  const additionalItem = generatorOverMyAdditionalAray.next();  
  // More code doing stuff with item and additionalItem
  console.log(item, additionalItem.value);
}

<!-- end snippet -->

Or a string:

<!-- begin snippet: js hide: true console: true babel: false -->

<!-- language: lang-js -->

const firstArray = [&quot;a&quot;, &quot;b&quot;, &quot;c&quot;];
const myAdditionalString = &quot;123&quot;;

const generatorOverMyAdditionalAray = myAdditionalString[Symbol.iterator]();

for (const item of firstArray) {
  // Initial code doing stuff with item
  const additionalItem = generatorOverMyAdditionalAray.next();  
  // More code doing stuff with item and additionalItem
  console.log(item, additionalItem.value);
}

<!-- end snippet -->

huangapple
  • 本文由 发表于 2023年5月17日 13:56:18
  • 转载请务必保留本文链接:https://go.coder-hub.com/76268940.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定