【问题标题】:Object's values sorted in desecending order对象的值按降序排序
【发布时间】:2021-03-07 10:16:49
【问题描述】:

我有这个对象:

gladiators = {
  Pesho: { Duck: '400' },
  Gladius: { Heal: '200', Support: '250', Shield: '250' }
}

每个角斗士都有自己的能力,因为值是每个能力的技能,我想按总技能降序打印它们,这就是我现在的位置:

for (let element in gladiators){ 
        console.log(`${element}: ${Object.values(gladiators[element]).map(Number).reduce((a, b) => a + b, 0)} skill`);
        for (let el in gladiators[element]){
            console.log(`- ${el} <!> ${gladiators[element][el]}`)
        }
    }

此代码打印:

Pesho: 400 skill
- Duck <!> 400
Gladius: 700 skill
- Heal <!> 200
- Support <!> 250
- Shield <!> 250

我只是想让它打印出来:

Gladius: 700 skill
- Shield <!> 250
- Support <!> 250
- Heal <!> 200
Pesho: 400 skill
- Duck <!> 400

我希望总技能按降序排列,如果相等,按升序排列,角斗士拥有的每个能力都相同。如果我读了几次指南有错误,请建议我如何使我的问题更清楚。

【问题讨论】:

    标签: javascript sorting object


    【解决方案1】:

    我们应该可以使用 Object.entries 和 Array.sort 来随意排列对象,然后打印出结果:

    gladiators = {
      Pesho: { Duck: '400' },
      Gladius: { Heal: '200', Support: '250', Shield: '250' }
    }
    
    // Get our array of gladiators, add total skill and add sorted abilities array.
    let result = Object.entries(gladiators).map(([name, glad]) => { 
        let abilities = Object.entries(glad);
        return { name, Total: abilities.reduce((acc, [k,v]) => acc + Number(v) , 0), abilities: abilities.sort(([k1,v1], [k2,v2]) => v2 - v1) };
    });
    
    // Sort the result in descending order by total skill.
    result.sort((a,b) => b.Total - a.Total);
    
    // Print out our result.
    result.forEach(res => { 
        console.log(`${res.name}: ${res.Total} skill`)
        res.abilities.forEach(([k,v]) => console.log(` - ${k} <!>`,v));
    })

    【讨论】:

      【解决方案2】:

      我会将您的计算拆分为一个单独的数组,并在输出之前对该新数组进行排序。例如:

      const gladiators = {
        Pesho: { Duck: '400' },
        Gladius: { Heal: '200', Support: '250', Shield: '250' }
      }
      
      const valueDescNameAsc = (a, b) => {
        if (a.value === b.value) return a.name.localeCompare(b.name)
        return a.value > b.value ? -1 : 1
      }
      
      // Transform data into arrays of objects (and calculate top-level value)
      const gladiatorSkills = Object.entries(gladiators)
        .map(([name, skills]) => ({
          name,
          value: Object.values(skills).map(Number).reduce((a, b) => a + b, 0),
          skills: Object.entries(skills).map(([name, value]) => ({ name, value })).sort(valueDescNameAsc)
        }))
        .sort(valueDescNameAsc)
      
      // Output the transformed gladiatorSkills data
      for (let { name, value, skills } of gladiatorSkills) {
        console.log(`${name}: ${value} skill`)
        for (let { name, value } of skills) {
          console.log(`- ${name} <!> ${value}`)
        }
      }

      【讨论】:

        【解决方案3】:

        构建对象时不考虑顺序。这是数组的工作。查看您的数据,拥有可以使用数组方法(例如排序)操作的角斗士列表会更合适。

        所以在下面的示例中,我将您的数据重写为对象数组,其中包含嵌套数组。这将保证订单将被兑现。

        它还会使代码的操作变得不那么复杂,因为您只是在处理数组,无需进行转换。 mapreducesort 的组合将带您到达您需要的地方。

        const gladiators = [
          {
            name: 'Pesho',
            stats: [
              {
                name: 'Duck',
                value: 400
              }
            ],
          },
          {
            name: 'Gladius',
            stats: [
              {
                name: 'Heal',
                value: 200
              },
              {
                name: 'Support',
                value: 300
              },
              {
                name: 'Shield',
                value: 250
              }
            ],
          },
        ];
        
        gladiators
        
          /**
           * Calculate the total skill and
           * sort the skills based on their value.
           */
          .map(({ name, stats }) => {
            const skill = stats.reduce((acc, { value }) => acc + value, 0);
            const sortedStats = stats.sort((a, b) => b.value - a.value);
            return { name, skill, stats: sortedStats };
          })
          
          /**
           * Sort the gladiators by skill (desc)
           */
          .sort((a, b) => b.skill - a.skill)
          
          /**
           * Print the data
           */
          .forEach((gladiator) => {
            console.log(`${gladiator.name}: ${gladiator.skill}`)
            gladiator.stats.forEach(({ name, value }) => {
              console.log(`- ${name} <!> ${value}`);
            });
          });

        【讨论】:

          【解决方案4】:

          我会通过创建一个新列表来简化这个问题,按总技能级别编制索引,然后对该列表进行排序,并记录每个条目;

          注意:此代码可以进一步简化,但我已将其发布为这样,以便 OP 清楚步骤;

          // Original data
          const data = { Pesho: { Duck: '400' }, Gladius: { Heal: '200', Support: '250', Shield: '250' } };
          
          // Index each gladiator on total skill
          let indexOnTotal = {};
          for (let obj of Object.entries(data)) {
            
              // Get obj value's
              const [name, skills] = obj;
            
              // Total Skill count
              const total = Object.keys(skills).reduce((sum,key)=>sum+parseFloat(skills[key]||0),0);
              
              // Add
              indexOnTotal[total] = obj;
          }
          
          // Sort
          let sorted = Object.keys(indexOnTotal).sort().reverse().map(key=> ({...indexOnTotal[key],key:key}) );
          
          // Log
          for (var g in sorted) {
          
              // Original gladiator
              const [ name, skills, total ] = Object.values(sorted[g]);
              
               // Name + Total
               console.log(`${name} (${total} skill)`);
              
              // Skills
              for (const [name, value] of Object.entries(skills)) {
                  console.log(`${name}: ${value}`);
              }
          }

          输出;

          Gladius (700 skill)
          Heal: 200
          Support: 250
          Shield: 250
          Pesho (400 skill)
          Duck: 400
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2016-03-10
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2016-09-05
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多