英文:
Make an iterator from an array
问题
我目前正在修改一些代码,尝试不影响初始<s>结构</s>代码。在数组上有一个for...of
循环,并且有第二个具有相同结构的数组,我想知道是否有一种快速的方法可以生成第二个数组的生成器以模拟zip。
这里是一个示例:
const firstArray = ["a", "b", "c"];
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爱好者,它会看起来像这样
>>> a = ["a", "b", "c"]
>>> b = [1, 2, 3]
>>> generator_over_b = (x for x in b)
>>> for item in a:
... additional_item = next(generator_over_b)
... print(item, additional_item)
...
a 1
b 2
c 3
编辑:强调了为什么for
或forEach
循环不是可行解决方案(最终未回答问题)。
英文:
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 = ["a", "b", "c"];
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
>>> a = ["a", "b", "c"]
>>> b = [1, 2, 3]
>>> generator_over_b = (x for x in b)
>>> 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 = ["a", "b", "c"];
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 => 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);
}
<!-- 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 = ["a", "b", "c"];
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 = ["a", "b", "c"];
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 = ["a", "b", "c"];
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 = ["a", "b", "c"];
const myAdditionalString = "123";
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 -->
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论