将一组值映射到百分比

Posted

技术标签:

【中文标题】将一组值映射到百分比【英文标题】:Map an array of values to percentages 【发布时间】:2021-02-21 15:01:57 【问题描述】:

为什么 map 不能在这些数组上工作?如何把这个数组变成百分比?

我正在尝试映射并解析从 API 返回的多个数组,但它仅映射每个数组中的第一个字符串,然后将其余字符串作为 NaN 返回。

我怀疑 forloop 可能会干扰地图的功能,但我不知道如何解决这个问题。

此外,当我检查数组上的数据类型时,它会作为对象返回。 我的目标是从给定的 8 个数字中取平均值,以百分比表示。

const apiInfo = $(".info");

function init() 
  $.ajax(
    url: "https://api.hatchways.io/assessment/students",
    method: "GET",
  ).then(function (res) 

    for (let i = 0; i < res.students.length; i++) 
      var curr = res.students[i];

      if (curr.id.includes("")) 

        $(".info");
        let img = $(
          "<img class='pPic float-left m-3' src='" +
            res.students[i].pic +
            "'alt = 'profile pic'>"
        );
        let title = res.students[i].firstName + " " + res.students[i].lastName;
        let email = res.students[i].email;
        let company = res.students[i].company;
        let skill = res.students[i].skill;

        let sGrades = res.students[i].grades

        console.log(typeof(sGrades))

        let x = sGrades.map(parseInt)

        let average = ""

        console.log(sGrades, x);

        let list = $("<div class='infoB'>");
        list.append(img);
        list.append("<h4 class='title'>" + title + "<h4>");
        list.append("<p class='mb-1 stats'> email: " + email + "</p>");
        list.append("<p class='mb-1 stats'> comapny: " + company + "</p>");
        list.append("<p class='mb-1 stats'> skill: " + skill + "</p>");
        list.append("<p class='mb-1 stats'> average: " + average + "</p>");

        $(".info").append(list);
      
    
  );


init();
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <meta
      name="viewport"
      content="width=device-width, initial-scale=1, shrink-to-fit=no"
    />
    <meta http-equiv="X-UA-Compatible" content="ie=edge" />
    <link
      rel="stylesheet"
      href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css"
      integrity="sha384-JcKb8q3iqJ61gNV9KGb8thSsNjpSL0n8PARn9HuZOnIxN0hoP+VmmDGMN5t9UJ0Z"
      crossorigin="anonymous"
    />
    <link
      rel="stylesheet"
      href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css"
    />
    <link rel="stylesheet" href="style.css" />
  </head>

  <body>
    <div class="container">
      <div class="info card scroll shadow p-3 mb-5 bg-white rounded"></div>
    </div>

    <script src="https://code.jquery.com/jquery-3.4.1.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.24.0/moment.min.js"></script>
    <script src="index.js"></script>
  </body>
</html>

【问题讨论】:

我认为parseInt 实际上是如何进行隐式映射的。我刚刚在我的控制台中尝试过,我也得到了NaN。你能不能把它改成这样:let x sGrades.map(num =&gt; parseInt(num)) 这可以将它们全部变成数字!谢谢!现在我只是将它们全部转换为百分比的问题!哈哈 百分比是什么意思?平均满分100?如果是,您可以使用sGrades.reduce((acc, ch)=&gt; acc + parseInt(ch), 0) / sGrades.length。会给你平均值。 【参考方案1】:

您可以通过以下方式平均这些值:

const avg = (arr) => arr.reduce((acc, val) => acc + val, 0) / arr.length;

您可以通过以下方式调用上述函数:

avg(student.grades.map(grade => parseInt(grade, 10)));

我还建议使用template literals 来构建您的输出 HTML。

演示

const apiInfo = $('.info');
const avg = (arr) => arr.reduce((acc, val) => acc + val, 0) / arr.length;

const renderStudentInfo = (student, $target) => 
  const fullName = student.firstName + ' ' + student.lastName,
    average = avg(student.grades.map(grade => parseInt(grade, 10)));
  $target.append($(`
    <div class="infoB">
      <img class="pPic float-left m-3"
        src="$student.pic"  />
      <h4 class="title">$fullName</h4>
      <p class="mb-1 stats">Email: $student.email</p>
      <p class="mb-1 stats">Company: $student.company</p>
      <p class="mb-1 stats">Skill: $student.skill</p>
      <p class="mb-1 stats">Average: $average.toFixed(2)%</p>
    </div>
  `));
;

const init = () => 
  $.ajax(
    url: 'https://api.hatchways.io/assessment/students',
    method: 'GET',
  ).then(( students ) => 
    students.forEach((student) => 
      if (student.id.includes('')) 
        renderStudentInfo(student, apiInfo);
      
    );
  );


init();
.infoB 
  margin-bottom: 1em;


.infoB .title 
  font-weight: bold;


.infoB .mb-1.stats 
  color: #444;
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.24.0/moment.min.js"></script>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css" />
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css" />
<div class="container">
  <div class="info card scroll shadow p-3 mb-5 bg-white rounded"></div>
</div>

【讨论】:

【参考方案2】:

您没有为地图提供适当的回调函数。 尝试将该行更改为此

let x = sGrades.map((v) => `$parseInt(v)%`)

但这会返回一个字符串数组。

【讨论】:

以上是关于将一组值映射到百分比的主要内容,如果未能解决你的问题,请参考以下文章

MFC中如何用for循环将一组值在编辑框中显示?

如何将一列的运行总计添加到 Access 查询?

将一列浮点数转换为累积百分比

SQL join:当值不在一组值中时如何选择

如何将一组地图从 Firestore 映射到 recyclerView?

将一列的值除以另一列