【问题标题】:How to use Iterators and generators to perform the following operations?如何使用迭代器和生成器来执行以下操作?
【发布时间】:2020-10-16 07:03:42
【问题描述】:

我想获取​data.json​文件,解析成一个对象,并使其成为可迭代对象。 (不要将对象数据类型更改为数组) 使其成为可迭代的使用

  1. 迭代器 2. 生成器 当该对象在 FOR OF 循环中传递时,我应该得到每个项目的输出,如下所示。 帖子 ID:1 标题:一些标题 帖子 ID:2 标题:其他标题 等等 … 这是 json 文件的链接[https://raw.githubusercontent.com/attainu/curriculum-master-fullstack/master/coding-challenges/deep-dive/iterators-data.json?token=AOGF265VMPYWFKXO6RNGXPS67WAMM][1]

console.log("connected");
function fetchJSONFile(path, callback) {
    var httpRequest = new XMLHttpRequest();
    httpRequest.onreadystatechange = function() {
        if (httpRequest.readyState === 4) {
            if (httpRequest.status === 200) {
                var data = JSON.parse(httpRequest.responseText);
                if (callback) callback(data);
            }
        }
    };
    httpRequest.open('GET', path);
    httpRequest.send(); 
}
fetchJSONFile(`https://raw.githubusercontent.com/attainu/curriculum-master-fullstack/master/coding-challenges/deep-dive/iterators-data.json?token=AOGF265VMPYWFKXO6RNGXPS67WAMM`, function(data)
{   
data[Symbol.iterator] = function() 
{
    var c=0;
  return {
      // I Don't know how to access the key of the object inside the object , Can you help me please?? 
    next() {
        c++;
      if (c <= data.length) {
        return { done: false, value: "value" };
      } else {
        return { done: true };
      }
    }
  }};
for (let val of data) {
  console.log(val); 
}
});

【问题讨论】:

  • HTTP 请求是异步的。您是否希望立即获得迭代器?因为这不是它真正的工作方式。只能异步获取这样的迭代器。
  • 你能详细说明一下吗?我完全不明白这个......提前谢谢......我在哪里可以阅读更多关于它的信息?
  • @trincot...请帮助
  • 我担心你试图解决的挑战是要求你在现在不可用但将来可用的东西上生成一个迭代器(对 HTTP 请求的响应)。您无法迭代尚不存在的内容,那么您是否有关于预期内容的更准确信息?
  • Sir @trincot ..这部分是否可以通过某种方式实现(当对象在 FOR OF 循环中传递时,我应该按照以下模式获得每个项目的输出。帖子 ID:1 标题:一些title Post ID: 2 Some other title 等等)??谢谢

标签: javascript json object iterator generator


【解决方案1】:

我已经用 fetch 试过了。您可以进行更改。 没挖。想出了这个。您必须定义自己的iterator。这是你想要的吗?

const fetch = require('node-fetch');

const arr = [];
let status;
fetch('https://raw.githubusercontent.com/attainu/curriculum-master-fullstack/master/coding-challenges/deep-dive/iterators-data.json?token=AOGF265VMPYWFKXO6RNGXPS67WAMM') // Call the fetch function passing the url of the API as a parameter
  .then((res) => {
    status = res.status;
    return res.json()
  })
  .then((jsonData) => {
    jsonData[Symbol.iterator] = function () {
      var self = this;
      var values = Object.keys(this);
      var i = 0;
      return {
        next: function () {
          return {
            value: self[values[i++]],
            done: i > values.length
          }
        }
      }
    }
   //you we can iterate over object
    for (var p of jsonData) {
      const obj = {
        "PostID": p.id,
        "Title": p.title
      }
      arr.push(obj)
    }
    console.log(arr)
  })
  .catch((err) => {
    // handle error for example
    console.error(err);
  });

【讨论】:

  • 我想要一个使用 symbol[iterator] 的解决方案
  • @ShivamYadav 更新了我的答案
【解决方案2】:

所以你被要求创建一个生成器和迭代器。

尚不清楚预期的内容:如果您在响应上创建迭代器,那么只有在已经收到响应时才有可能,而不是在您启动 HTTP 请求时。所以迭代器只能存在于未来,在响应返回时。

至少有两种不同的方法可以做到这一点:

1。立即创建一个迭代器,但是一个 async 一个

这样您可以立即创建它,但生成的迭代器将产生承诺,而不是实际的响应值。使用for await ... of,您可以以异步方式从该迭代器中获取值。

看起来是这样的:

async function * generator(path) {
    const obj = await fetch(path).then(resp => resp.json());
    for (const postId in obj) yield obj[postId];
}

// The main program has to be asynchronous:
(async (path) => {
    // Consume the async iterator that you get from the async generator
    console.log("wait for it...");
    for await (let { id, title } of generator(path)) {
        console.log("postId: ", id, "title: ", title); 
    }
})("https://raw.githubusercontent.com/attainu/curriculum-master-fullstack/master/coding-challenges/deep-dive/iterators-data.json?token=AOGF265VMPYWFKXO6RNGXPS67WAMM");

2。收到响应后才创建迭代器

在这里您创建一个普通的迭代器,并且仅在您收到响应时:

function * generator(obj) {
    for (const postId in obj) yield obj[postId];
}

// The main program has to be asynchronous:
(async (path) => {
    console.log("wait for it...");
    // Perform the request
    const obj = await fetch(path).then(resp => resp.json());
    // Consume the iterator that you get from the generator
    for (let { id, title } of generator(obj)) {
        console.log("postId: ", id, "title: ", title); 
    }
})("https://raw.githubusercontent.com/attainu/curriculum-master-fullstack/master/coding-challenges/deep-dive/iterators-data.json?token=AOGF265VMPYWFKXO6RNGXPS67WAMM");

【讨论】:

  • @ShivamYadav 您真正在寻找两种实现中的哪一种?第二个,对吧?
  • @trincot ..对不起先生,但你能解释一下这部分吗..我如何在收到响应后创建一个迭代器..这超出了我的水平理解:(
  • 这是我回答的第二个 sn-p 中发生的情况。注意 JSON 响应是如何等待的。只有当该承诺解决时,代码执行才会在此之后调用generate,以便它返回响应对象上的迭代器。
  • 实际上,我看到您可能对响应对象的顶级键不感兴趣,但对id 属性...我为此更新了答案。
  • @trincot 再次感谢您,先生...我非常感谢您的所有帮助 :) 感谢您
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-05-28
  • 1970-01-01
  • 1970-01-01
  • 2016-03-23
  • 1970-01-01
  • 2018-05-16
  • 1970-01-01
相关资源
最近更新 更多