如何计算2个Javascript对象之间匹配的百分比?

时间:2017-02-10 15:43:26

标签: javascript

我需要计算2个Javascript对象之间匹配的百分比。我怎样才能做到这一点?

示例:

<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"/>
<div class="row">
  <div class="itemGrid">
    <div class="col-xs-1">test</div>
    <div class="col-xs-10">
      <table>
        ... 4 TD columns, 4 tr rows, no content of fixed widths
      </table>
    </div>
    <div class="col-xs-1">test</div>
  </div>
</div>

3 个答案:

答案 0 :(得分:5)

从您的有限数量的示例中确切地知道它应该如何表现并不完全清楚,但我相信您的要求可以重新措辞:

  

obj1obj2中有多少百分比的项目存在且相等?

为此,您可以简单地计算:

var count = [0,0];
for( var key in obj1) {
    count[1]++; // total count
    if( obj2.hasOwnProperty(key) && obj2[key] === obj1[key]) {
        count[0]++; // match count
    }
}
var percentage = count[0]/count[1]*100+"%";

当然,如果你的规格不同,那么这不太合适,但至少应该让你朝着正确的方向前进。

答案 1 :(得分:4)

您尚未准确指定计算此百分比的方式。测量两个对象之间的百分比相似性至少有四种不同的方法:

  • 第一个对象中可以在第二个
  • 中找到的键的百分比
  • 第一个对象中可以在第二个中找到的值的百分比,包括重复项,
  • 第一个对象中可以在第二个中找到的值的百分比,不允许重复,并且
  • 第一个对象中可以在第二个对象中找到的{key:value}对的百分比。

请注意,两个对象的顺序很重要,即使用(obj1,obj2)调用可能会产生与调用(obj2,obj1)不同的结果。

上面的第二个选项计算第二个对象中每个重复值的实例,从而可以返回高于100%的值,例如比较{a:42}和{x:42,y:42}返回200%。这可能最初看起来不合理,但根据计算的定义方式在数学上是有效的。在第三个选项中不允许这样的重复,因此比较{a:42}和{x:42,y:42}将返回100%。在任何一种情况下,第一个对象中的重复值都不计算,例如在两种情况下,比较{a:42,b:42}和{x:42}得到50%。由于JavaScript对象不能有重复的键,因此这些重复项不是上述第一个和第四个选项的相关考虑因素。

下面的代码片段演示了所有四种方法。

const obj1 = {a: 1, b: 2, c: 3, d: 3};
const obj2 = {a: 1, b: 1, e: 2, f: 2, g: 3, h: 5};

const keys = obj => Object.keys(obj);
const toPct = a => 100 / keys(a).length;

const pctSameKeys = (a, b) =>
  keys(b).reduce((num,key) =>
    keys(a).indexOf(key) > -1 ? num + 1 : num, 0) * toPct(a);

const pctSameValuesIncludingDuplicates = (a, b) =>
  keys(b).map(key => b[key]).reduce((num,v) =>
    keys(a).map(key => a[key]).indexOf(v) > -1 ? num + 1 : num, 0) * toPct(a);

const pctSameValuesNoDuplicates = (a, b) =>
  Array.from(new Set(keys(b).map(key => b[key]))).reduce((num,v) =>
    keys(a).map(key => a[key]).indexOf(v) > -1 ? num + 1 : num, 0) * toPct(a);

const pctSameProps = (a, b) =>
  keys(b).reduce((num,key) =>
    a[key] === b[key] ? num + 1 : num, 0) * toPct(a);

console.log('obj1:', JSON.stringify(obj1));
console.log('obj2:', JSON.stringify(obj2));
console.log('% same keys:                   ', pctSameKeys(obj1, obj2));
console.log('% same values, incl duplicates:', pctSameValuesIncludingDuplicates(obj1, obj2));
console.log('% same values, no duplicates:  ', pctSameValuesNoDuplicates(obj1, obj2));
console.log('% same properties (k/v pairs): ', pctSameProps     (obj1, obj2));

以下代码片段显示的内容完全相同,但是以更实用的方式编写(但请参阅this answer on the Computer Engineering site以查看此处的代码如何可以在仍然可用但更易读的情况下重写样式):

const obj1 = {a: 1, b: 2, c: 3, d: 3};
const obj2 = {a: 1, b: 1, e: 2, f: 2, g: 3, h: 5};

// x or X is key or value or key/value pair

const getXs = (obj, getX) =>
  Object.keys(obj).map(key => getX(obj, key));

const getPctSameXs = (getX, filter) =>
  (objA, objB) =>
    (filter ? filter(getXs(objB, getX)) : getXs(objB, getX)).reduce(
      (numSame, x) =>
        getXs(objA, getX).indexOf(x) > -1 ? numSame + 1 : numSame,
      0
    ) / Object.keys(objA).length * 100;

const pctSameKeys       = getPctSameXs((obj, key) => key);
const pctSameValsDups   = getPctSameXs((obj, key) => obj[key]);
const pctSameValsNoDups = getPctSameXs((obj, key) => obj[key], vals => [...new Set(vals)]);
const pctSameProps      = getPctSameXs((obj, key) => JSON.stringify( {[key]: obj[key]} ));

console.log('obj1:', JSON.stringify(obj1));
console.log('obj2:', JSON.stringify(obj2));
console.log('% same keys:                   ', pctSameKeys      (obj1, obj2));
console.log('% same values, incl duplicates:', pctSameValsDups  (obj1, obj2));
console.log('% same values, no duplicates:  ', pctSameValsNoDups(obj1, obj2));
console.log('% same properties (k/v pairs): ', pctSameProps     (obj1, obj2));

答案 2 :(得分:0)

你的问题很清楚细节。所以我假设你想在1个Array对象中查找值,看看它们是否出现在第二个数组中。

您有两种选择。

1。)使用HashMap - 将它们转换为表,然后连接它们的值。内连接应该只返回它们之间通用的东西,从而给你一个计数。

2。)使用Array - 将大数组转换为哈希映射。遍历小数组并查看HashMap中是否存在小数组中的值。如果他们这样做,那么你可以保持运行计数。

3。)定期{ "version": "0.2.0", "configurations": [ { "name": "Launch on iOS", "type": "nativescript", "request": "launch", "platform": "ios", "appRoot": "${workspaceRoot}", "sourceMaps": true, "watch": true }, { "name": "Attach on iOS", "type": "nativescript", "request": "attach", "platform": "ios", "appRoot": "${workspaceRoot}", "sourceMaps": true, "watch": false }, { "name": "Launch on Android", "type": "nativescript", "request": "launch", "platform": "android", "appRoot": "${workspaceRoot}", "sourceMaps": true, "watch": true }, { "name": "Attach on Android", "type": "nativescript", "request": "attach", "platform": "android", "appRoot": "${workspaceRoot}", "sourceMaps": true, "watch": false } ] } 搜索 - 就像通常通过数组一样,你可以看到是否有匹配。