【问题标题】:How to consume JSON data and ignore repeated values?如何消费 JSON 数据并忽略重复值?
【发布时间】:2021-08-20 20:59:54
【问题描述】:

我正在使用 Google Books API 来显示简单图书搜索的结果。但是,在执行搜索时,某些项目会重复返回。见:book-search

要获取这些数据并在 HTML 中显示,我这样做:

var result = document.getElementById("result");
var cover, title, author, book_id;
function handleResponse(response) {
  for (var i = 0; i < response.items.length; i++) {
    var item = response.items[i];
    // Create elements
    figure = document.createElement("figure");
    aEmp = document.createElement("a");
    aId = document.createElement("a");
    img = document.createElement("img");
    figcap = document.createElement("figcaption");
    // Get data from JSON
    try {
      cover = item.volumeInfo.imageLinks.thumbnail;
      title = item.volumeInfo.title;
      author = item.volumeInfo.authors;
      book_id = item.id;
    } catch (error) {
      continue;
    } finally {
      // Set value to elements e send to HTML
      result.appendChild(figure);
      aEmp.appendChild(img);
      aId.innerHTML = "ADICIONAR";
      aId.href = `/add/${book_id}`;
      aId.classList.add("dropdown");
      figure.appendChild(aId);
      figure.appendChild(aEmp);
      img.src = cover;
      figcap.innerHTML += `${title}<br>${author}`;
      figure.appendChild(figcap);
    }
  }
}
document.querySelector("form").addEventListener("submit", function (e) {
  result.innerHTML = "";
  search = document.getElementById("search").value;
  var script = document.createElement("script");
  script.src = `https://www.googleapis.com/books/v1/volumes?q=${search}&callback=handleResponse`;
  document.body.appendChild(script);
  e.preventDefault();
});

这是我上传的图片上使用的 JSON 示例:

https://www.googleapis.com/books/v1/volumes?q=$harry+potter&callback=handleResponse

【问题讨论】:

    标签: javascript json callback google-books-api


    【解决方案1】:

    Google 响应数组中的每个项目似乎都包含一个唯一 ID。在您的回调函数中,遍历返回结果的数组;记住已经在字典/哈希表中看到的 ID。如果之前看到过的 ID 再次出现,请跳过该记录。

    【讨论】:

    • 好主意!我会尽力做到这一点。
    【解决方案2】:

    查看了您最后提供的 JSON 数据,但我没有发现 API 响应有任何重复。无法弄清楚数据中可能在哪里进行了重复。

    【讨论】:

    • 是的,我也意识到了。我不知道为什么会这样。
    • 嗨@jateen,欢迎来到!考虑为此类讨论添加 cmets。
    【解决方案3】:

    我在您的 API 搜索中没有看到任何重复值。

    我确实用fetch 承诺替换了脚本插入回调黑客。这应该会更好。

    const results = document.querySelector('.results');
    const googleBooksApi = 'https://www.googleapis.com/books/v1';
    
    const formatList = (items) => {
      switch (items.length) {
        case 0: return '';
        case 1: return items[0];
        case 2: return items.join(' and ');
        default: return `${items.slice(0, -1).join(', ')} and ${[...items].pop()}`;
      }
    };
    
    // Convenience promise
    const fetchBooks = (path) =>
      fetch(`${googleBooksApi}/${path}`)
        .then(response => response.json());
    
    const queryBooksVolumes = (term) =>
      fetchBooks(`volumes?q=${term.replace(' ', '+')}`);
    
    const addBook = (book) => {
      // Create elements
      const figure = document.createElement('figure');
      const aEmp = document.createElement('a');
      const aId = document.createElement('a');
      const img = document.createElement('img');
      const figcap = document.createElement('figcaption');
      const figcapTitle = document.createElement('div');
      const figcapAuthors = document.createElement('div');
      
      // Destructure data fields from book object (JSON)
      const {
        id: bookId,
        volumeInfo: {
          title,
          authors,
          publishedDate,
          imageLinks: { thumbnail }
        }
      } = book;
    
      const year = new Date(publishedDate).getFullYear();
    
      figure.classList.add('figure');
      aEmp.appendChild(img);
      aId.innerHTML = 'ADICIONAR';
      aId.href = `/add/${bookId}`;
      aId.classList.add('dropdown');
      figure.appendChild(aId);
      figure.appendChild(aEmp);
      img.src = thumbnail;
      figcapTitle.classList.add('figcap-title');
      figcapTitle.textContent = `${title} (${year})`;
      figcapAuthors.classList.add('figcap-authors');
      figcapAuthors.textContent = formatList(authors);
      figcap.append(figcapTitle);
      figcap.append(figcapAuthors);
      figure.appendChild(figcap);
      results.appendChild(figure);
    };
    
    const populateResults = ({ items }) => items
      .sort((
          { volumeInfo: { title: a } },
          { volumeInfo: { title: b } }
        ) =>
          a.localeCompare(b))
      .forEach(addBook);
    
    const handleSearch = (e) => {
      e.preventDefault();
      const query = e.target.elements.search.value.trim();
      results.innerHTML = '';
      if (query.length > 0) {
        queryBooksVolumes(query).then(populateResults);
      }
    };
    
    document.forms['book-search'].addEventListener('submit', handleSearch);
    html, body { width 100%; height: 100%; margin: 0; padding: 0; }
    
    form { padding: 0.5em; }
    
    .results {
      display: flex;
      flex-direction: row;
      /*flex-wrap: wrap;*/
      align-items: top;
    }
    
    form label { font-weight: bold; }
    form label::after { content: ':'; }
    
    .figure {
      display: flex;
      flex-direction: column;
      justify-content: center;
      border: thin solid grey;
      align-items: center;
      padding: 0.5em;
    }
    
    .figcap-title { font-weight: bold; }
    .figcap-authors { font-style: italic; }
    
    .figure img {
      margin: 0.5em 0;
    }
    <form name="book-search">
      <label>Book Title</label>
      <input type="text" name="search" value="Harry Potter" placeholder="Enter a book title..."/>
      <button>Search</button>
    </form>
    <div class="results"></div>

    【讨论】:

    • 非常感谢,看来真的会流畅很多。我会申请的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-10
    • 2014-02-13
    • 1970-01-01
    • 2022-07-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多