如何获取数组中最高的数字和相应的名称?

时间:2018-04-05 14:17:04

标签: javascript arrays json promise fetch

我有一个从API中提取数据的表。现在我想解析数据并获得最高的高度和随之而来的名称。数据来自https://swapi.co/api/species/1/以下是可以工作的代码并将数据导入表中:

const url = 'https://swapi.co/api/species/1/';
 function fetchData(url) {
   return fetch(url).then((resp) => resp.json());
 }

   function constructTableRow(data) {
     const row = document.createElement('tr');
     const { name, height, mass, hair_color } = data;
     row.appendChild(constructElement('td', name))
     row.appendChild(constructElement('td', height))
     row.appendChild(constructElement('td', mass))
     row.appendChild(constructElement('td', hair_color))
     return row;
 }

    const swTable = document.getElementById('sw-table').getElementsByTagName('tbody')[0];
   fetchData(url).then(data =>
   data.people.forEach(personUrl =>
   fetchData(personUrl).then(result => {
     const row = constructTableRow(result);
     swTable.appendChild(row);
   })
 )
);

以下是问题代码:

   const getAvgHeight = async url =>
  fetch(url)
   .then(r => r.json())
   .then(
       async data =>
       (await Promise.all( 
        data.people.map( personUrl => 
           fetch(personUrl) 
             .then(r => r.json())
             .then(person => parseInt(person.height)) 
         )
       // filter out unkwown
      )).filter(height => !isNaN(height)) 
   )
   const maxHeight = height.Math.max(height)
  .then(heights => heights(maxHeight)); 
 getAvgHeight("https://swapi.co/api/species/1/").then(result => 
 document.getElementById('sw-tall').innerHTML = result.toFixed(2));

当我运行此代码时,我收到错误:height is not defined

缺少什么?

1 个答案:

答案 0 :(得分:1)

我看到你重复使用上一个问题/答案的平均质量代码(获得所述人员的平均质量)。这是有道理的,这个过程实际上非常相似,而你几乎就在那里。 :)

你的函数名为getAvgHeight,但它似乎试图获得最大高度,所以我认为这是你想要的。

问题主要在于:

const maxHeight = height.Math.max(height)

首先,height未在该上下文中定义,它在获取人员数据期间仅在Promise.all(…)内使用。

其次,即使你定义了身高,Math.max也不会这样:

[202, 177, 165].Math.max() // nope, arrays don't have Math at all
Math.max([202, 177, 165]) // this would make sense, sort of… but Math.max expects the actual numbers, not an array of them, and it returns NaN (because an array is not a number)
Math.max(202, 177, 165) // this works, returns 202
Math.max(...[202, 177, 165]) // this would also work, read more about it here if you want: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax

您可能希望阅读Math.max的文档:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/max

所以,你可以得到这样的最大数字(身高),但你在这个过程中丢失了相关的名字。

最好按照高度对数组中的人进行排序,然后获得第一个(=最高)的人。甚至所有这些,排序:



const getPersonsByHeight = async url =>
  fetch(url)
    .then(r => r.json())
    .then(
      async data =>
        (await Promise.all(
          data.people.map(personUrl =>
            fetch(personUrl)
              .then(r => r.json())
              .then(person => ({
                // keep the name:
                name: person.name,
                // and height converted to integer:
                height: parseInt(person.height)
              })) // => { "name": "Darth Vader", "height": 202 }
          )
        ))
          .filter(person => !isNaN(person.height))
          // sort array by person.height:
          .sort((personA, personB) => personB.height - personA.height)
          // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort
    );
    
    /* ->
    [
      {
        "name": "Darth Vader",
        "height": 202
      },
      {
        "name": "Qui-Gon Jinn",
        "height": 193
      },
      {
        "name": "Dooku",
        "height": 193
      },
      …
    ]
    */

getPersonsByHeight("https://swapi.co/api/species/1/").then(people =>{
  console.log(`highest: ${people[0].name}`); // people[0] is the first person, people[1] the second etc.
  console.log('height chart using forEach:');
  people.forEach((person, index) => console.log(`${index + 1}. ${person.name}, ${person.height} cm`))
});