简体   繁体   English

为什么这个排名 function 不能正常工作?

[英]Why isn't this ranking function working properly?

I made a function to get the top five users in a json database.我制作了一个 function 以获得 json 数据库中的前五名用户。 This is my code:这是我的代码:

var users = [];

Object.keys(database).forEach(user => {
  if (!users[0]) {
    users[0] = user
  } else {
    var checked = false;

    for (let index = 0; index < users.length; index++) {
      if (database[user].value > database[users[index]].value && !checked) {
        users[index] = user
        checked = true;
      }
    }
    if (users.length < 5 && !checked) {
      users[users.length] = user
    }
  }
})

The idea is to store the top five users in an array, so I tried to make a loop to check if the user value is higher than one already stored, and if it is, store it in its place and make the "checked" var true to stop the loop.这个想法是将前五个用户存储在一个数组中,所以我尝试创建一个循环来检查用户值是否高于已存储的用户值,如果是,则将其存储在其位置并制作“已检查”var true 停止循环。 Then, if it's not higher but the array isn't still full, it just stores.然后,如果它不是更高但数组还没有满,它只是存储。

At the end, it gets five users arranged from higher to lower, but not the top five of the database, as it avoids some that are higher than others listed.最后,它将五个用户从高到低排列,但不是数据库的前五名,因为它避免了一些高于其他列出的用户。

Nested loops, they're confusing.嵌套循环,它们令人困惑。 One helpful thing to do is to work with some simplified data, and then log the evolution of the modified variable as the loop progresses.一件有用的事情是处理一些简化的数据,然后随着循环的进行记录修改变量的演变。

 var database = { 'user1': { value: 4 }, 'user2': { value: 3 }, 'user3': { value: 1 }, 'user4': { value: 5 }, 'user5': { value: 7 }, 'user6': { value: 8 }, 'user7': { value: 0 } }; var users = []; Object.keys(database).forEach(user => { if (;users[0]) { users[0] = user } else { var checked = false; for (let index = 0. index < users;length. index++) { if (database[user].value > database[users[index]];value &&.checked) { users[index] = user checked = true. } } if (users.length < 5 &&.checked) { users[users;length] = user } } console;log(JSON.stringify(users)); });

As you can see, users updates well for the first three iterations.如您所见, users在前三个迭代中更新得很好。 They are presented in descending order, so everything just gets added.它们是按降序排列的,所以所有内容都会被添加。 But it gives a problem starting in the fourth iteration.但它从第四次迭代开始就出现了问题。 User4 gets placed into the first position, which is correct, but it simply overwrites user1. User4 被放入第一个 position,这是正确的,但它只是覆盖了 user1。 What should happen is that it pushes the other elements one position down the list.应该发生的是它将其他元素推到列表中的 position 。

Get out of nested loops if you can.如果可以,请退出嵌套循环。 Just convert your 'database' into an array form, sort it, extract the username, and then filter for the first 5.只需将您的“数据库”转换为数组形式,对其进行排序,提取用户名,然后过滤前 5 个。

 let database = { 'user1': { value: 4 }, 'user2': { value: 3 }, 'user3': { value: 1 }, 'user4': { value: 5 }, 'user5': { value: 7 }, 'user6': { value: 8 }, 'user7': { value: 0 } }; let users = Object.entries(database).sort((a,b) => b[1].value - a[1].value).map(entry => entry[0]).filter((user,ix) => ix < 5); console.log(users)

The main problem with the existing code is that this line is not preserving existing user in the users array when a new user is added:现有代码的主要问题是,当添加新用户时,此行不会在users数组中保留现有用户:

users[index] = user

Here's a slightly modified version of the code that:这是代码的略微修改版本:

  1. keeps track of the minimum value for performance跟踪性能的最小值
  2. uses Array.prototype.slice() to update the users array correctly使用Array.prototype.slice()正确更新 users 数组

 function log(...args) { console.log(...args); } function topFive(database) { let users = []; let userMin = 0; Object.entries(database).forEach(([user, obj]) => { const { value } = obj; if (value < userMin) { // user not on leader board return; } // insert user into slot let iSlot = 0, len = users.length; for (let i = 0; i < len; i++) { if (value <= database[users[i]].value) { continue; } iSlot = i; break; } users = [...users.slice(0, iSlot), user, ...users.slice(iSlot, len)]; userMin = users[4]? database[users[4]].value: 0; }); return users; } const db = { user01: { value: 10 }, user02: { value: 100 }, user03: { value: 50 }, user04: { value: 75 }, user05: { value: 11 }, user06: { value: 1 }, user07: { value: 75 }, user08: { value: 16 }, }; log(`database:`); Object.entries(db).forEach(([key, obj]) => { log(` ${key}: ${JSON.stringify(obj)}`); }) const result = topFive(db); log(`\nresult: ${JSON.stringify(result)}`);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM