【问题标题】:How can I find remaining percentages if one or two percentages are known如果已知一两个百分比,我如何找到剩余百分比
【发布时间】:2021-11-23 10:32:12
【问题描述】:

考虑以下对象:

// Example 1

{
    gradeA: 100,
    gradeB: 'No-Data',
    gradeC: 'No-Data'
}
// Example 2

{
   gradeA: 50,
   gradeB: 40,
   gradeC: 'No-Data'
}
// Example 3

{
   gradeA: 75,
   gradeB: 'No-Data',
   gradeC: 'No-Data'
}

它们代表一个百分比,即所有三个等级的总和正好是 100。我们如何在可以计算它们的值时插入带有 'No-Data' 的键?

预期结果:

// Example 1

{
    gradeA: 100,
    gradeB: 0,
    gradeC: 0
}
// Example 2

{
   gradeA: 50,
   gradeB: 40,
   gradeC: 10
}
// Example 3

{
   gradeA: 75,
   gradeB: 'No-Data',
   gradeC: 'No-Data'
}

// Note: This one can't be figured out so we leave it as is.

我的伪代码解决方案:

function interpolate(obj) {
    // If only one key is a number:
    //    The value is 100:
    //        Set the other two keys to 0 and return the obj.
    //    The value is less than 100:
    //        return obj unchanged.
    // If only one key is not a number:
    //    set that key to the sum of the two numbers minus 100 and return the obj.
}

这里有两个主要问题:

  1. 如何知道'No-Data'. 有多少和哪些键
  2. 我可以重新安排控制流以提高效率吗?

实际上,这些对象位于一个数组中,但我确信我可以自己解决这些问题。

【问题讨论】:

  • 我猜你的意思是 40 在第二个示例的 gradeB 字段中
  • @GuerricP 是的。我已经更正了。
  • 除此之外,您的算法很好并且可以正常工作,所以我认为您应该发布实际代码,并且可能在codereview.stackexchange.com 上进行更合适的操作。除非您对此有更具体的问题。

标签: javascript node.js algorithm


【解决方案1】:
  1. 您可以使用 this 之类的东西来过滤给定值的键(在您的情况下为 No-Data)。

let keys = Object.keys(obj).filter(k=>obj[k]===value);

只需计算数组中的项目数,看看你有多少。

  1. 您的控制流很好,它是可读的,其效率取决于您计算No-Data 出现次数的效率。提示:如果您想尽可能提高效率,则无需在找到 2 后继续查找 No-Data 的出现 :)

附言。发布的其他代码存在一些问题,如果您将其提交,可能会阻止您获得满分:)

【讨论】:

  • 应该这样做!让我编写代码,如果可以的话,我会在这里分享。看看我能不能有效率。
  • 祝你好运 :) 如果您正在寻找评论,我会支持 @GuerricP 使用 codereview.stackexchange.com 的建议。另一个提示是,在 某个时间点,您将需要遍历对象以计算 No-Data 的出现次数,并且您还需要迭代以计算总数(看看它是否添加到 100)。在同一迭代中执行这两项操作将快两倍。
【解决方案2】:

使用您描述的相同逻辑:

function interpolate(obj) {
  var noData = 0;
  Object.keys(obj).forEach(key => {
    if (isNaN(obj[key])) {
      noData++;
    }
  });

  var sum = 0;
  var missingKey;
  if (noData == 1) {
    Object.keys(obj).forEach(key => {
      if (!isNaN(obj[key])) {
        sum += obj[key];
      } else {
        missingKey = key;
      }
    });
    obj[missingKey] = 100 - sum;
    return obj
  }
  return obj;
}

var objects = [{
  gradeA: 100,
  gradeB: 'No-Data',
  gradeC: 'No-Data'
}, {
  gradeA: 50,
  gradeB: 40,
  gradeC: 'No-Data'
}, {
  gradeA: 75,
  gradeB: 'No-Data',
  gradeC: 'No-Data'
}]

objects.forEach(o => console.log(interpolate(o)));

【讨论】:

  • 这就像我通过 Copilot 提出了我的整个问题。谢谢!
【解决方案3】:

在我的解决方案中,我分析每个对象的成绩总和和无数据值的数量。然后,如果条件匹配,我将继续替换每个对象的每个属性中的 No-Data 值。适用于任意数量的成绩。

const objects = [{
    gradeA: 100,
    gradeB: 'No-Data',
    gradeC: 'No-Data'
}, {
   gradeA: 50,
   gradeB: 40,
   gradeC: 'No-Data'
}, {
   gradeA: 75,
   gradeB: 'No-Data',
   gradeC: 'No-Data'
}];

const analysis = objects
  .map( o => Object.values(o)
    .reduce( ([o, sum, nodatacount], v) =>
      v==='No-Data'
      ? [o, sum, nodatacount+1] 
      : [o, sum+v, nodatacount], 
      [o, 0, 0] ) );

for(const [o, sum, nodatacount] of analysis) {
  if(sum === 100 || nodatacount === 1) {
    for(const [key, _] of Object.entries(o)
      .filter(([_, value]) => value==='No-Data')
      ) {
      o[key] = 100-sum;
    }
  }
}

console.log( objects );
.as-console-wrapper {top:0; max-height: 100% !important}

【讨论】:

    【解决方案4】:

    您可以先找到带有filter 的数字,然后从长度中减去它以获得非数字的长度。然后,如果该长度大于 1 并且没有最大值,则返回相同的对象。否则,您会找到总计并创建返回具有正确值的新对象。

    function interpolate(obj, max = 100) {
      const numbers = Object.values(obj).filter(Number)
      const notNumbers = Object.keys(obj).length - numbers.length
      const isMax = numbers.includes(max)
    
      if (notNumbers > 1 && !isMax) {
        return obj
      }
    
      const output = {}
      const total = numbers.reduce((r, e) => r + e, 0);
    
      for (const [k, v] of Object.entries(obj)) {
        output[k] = typeof v !== 'number' ? isMax ? 0 : max - total : v
      }
    
      return output
    }
    
    const a = {
      gradeA: 100,
      gradeB: 'No-Data',
      gradeC: 'No-Data'
    }
    
    const b = {
      gradeA: 50,
      gradeB: 40,
      gradeC: 'No-Data'
    }
    
    const c = {
      gradeA: 75,
      gradeB: 'No-Data',
      gradeC: 'No-Data'
    }
    
    
    console.log(interpolate(a))
    console.log(interpolate(b))
    console.log(interpolate(c))

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-11-13
      • 2022-11-05
      • 2021-07-06
      • 2018-05-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-05-27
      相关资源
      最近更新 更多