我正在尝试计算输出百分比的值数组的一致性。因此,例如[1,1,1,1,1]的数组将输出100%的一致性,[1,12,23,5,2]的数组将输出类似25%的一致性。
我尝试了一个简单的百分比差异计算,但仅适用于两个数字,而这需要适用于动态数组,这只会输出差异。任何帮助将不胜感激,所以提前感谢。
function getPercentage(n1, n2){
var newValue = n1 - n2;
return (newValue / n1) * 100;
}
getPercentage(1, 12)
答案 0 :(得分:1)
好的,这是我第一次尝试,尝试将其制作成更小的代码单元,以便更轻松地完成工作。如果我有足够的时间可以进一步完善,但随后可读性向南; - )
试图避免使用TypeScript并尽可能保持ECMAScript 5友好。 (抱歉格式混乱)
let ar100 = [1,1,1,1,1];
let ar25 = [1,12,23,5,2];
/**
* Calculate the lack of difference between two values (ie consistency)
* @param {number} valA
* @param {number} valB
* @returns {number} The consistency as a decimal
* where 1 is '100% consistent'
* and 0.5 is '50% consistent'
*/
var calcConsistency = function( valA, valB) {
let diff = Math.abs(valA - valB);
let consistency = (valA - diff) / valA;
// assumption: you can't be less than zero consistent
return consistency < 0 ? 0 : consistency;
}
/**
* A predicate used by the map operation in 'overallConsistency'
* @param {*} val
* @param {*} index
* @param {*} values
* @return {number} the average consistency of the current 'val' to the other 'values'
*/
var mapEachConsistency = function(val, index, values) {
let predicateGetOnlyOthers = function(currentValue, othersIndex) {
return index !== othersIndex;
};
let others = values.filter(predicateGetOnlyOthers);
const otherCount = others.length;
let totalConsistency = others.reduce(function(previousValue, currentValue) {
return previousValue + calcConsistency(val, currentValue);
});
return (totalConsistency / otherCount);
}
/**
* Calculate the overall average consistency of an array of numbers
* @param {Array<number>} arrayOfValues
* @return {number} The average consistency score as percentage
*/
var overallConsistency = function(arrayOfValues) {
let consists = arrayOfValues.map(mapEachConsistency);
let sumTotal = function(previous, current){ return previous + current; };
let avgAnswer = consists.reduce(sumTotal);
return (avgAnswer / consists.length) * 100;
};
// Here's using it to see the results
var answer = overallConsistency(ar100);
console.log(`Consistency: ${answer.toFixed(3)}% (fixed to 3 dicimal place)`);
answer = overallConsistency(ar25);
console.log(`Consistency: ${answer.toFixed(3)}% (fixed to 3 dicimal place)`);
答案 1 :(得分:1)
根据您的评论,我改进了用于计算数组成员之间整体一致性的基值。
计算出的新结果(在视觉检查上似乎看似合理,再次取决于所有成员的一致性定义,但我认为这种情况越来越接近):
$ node jsscratch.js
Consistency for 1,1,1,1,1 is 100.000% fixed to 3 decimal places
Consistency for 1,12,23,5,2 is 33.360% fixed to 3 decimal places
Consistency for 1,12,23,15,12 is 50.160% fixed to 3 decimal places
Consistency for 1,2,10 is 83.778% fixed to 3 decimal places
/**
* Calculate the expected value
*/
function expectancy(arrayOfValues) {
let sumTotal = function(previousValue, currentValue) {
return previousValue + currentValue;
};
let u = arrayOfValues.reduce(sumTotal);
// Assume each member carries an equal weight in expected value
u = u / arrayOfValues.length;
return u;
}
/**
* Calculate consistency of the members in the vector
* @param {Array<number>} The vector of members to inspect for similarity
* @return {number} The percentage of members that are the same
*/
var similarity = function(arrayOfValues) {
let sumTotal = function(previousValue, currentValue) {
return previousValue + currentValue;
};
// Step 1: Calculate the mean value u
let u = expectancy(arrayOfValues); // Calculate the average
// Step 2: Calculate the standard deviation sig
let sig = [];
let N = 1/arrayOfValues.length;
for (let i = 0; i < arrayOfValues.length; i++) {
sig.push(N*(arrayOfValues[i] - u) * (arrayOfValues[i] - u));
}
// This only works in mutable type, such as found in JavaScript, else sum it up
sig = sig.reduce(sumTotal);
// Step 3: Offset from 100% to get the similarity
return 100 - sig;
}
answer = similarity(ar1);
console.log(`Consistency for ${ar1} is ${answer.toFixed(3)}% fixed to 3 decimal places`);
answer = similarity(ar2);
console.log(`Consistency for ${ar2} is ${answer.toFixed(3)}% fixed to 3 decimal places`);
answer = similarity(ar3);
console.log(`Consistency for ${ar3} is ${answer.toFixed(3)}% fixed to 3 decimal places`);
answer = similarity(ar4);
console.log(`Consistency for ${ar4} is ${answer.toFixed(3)}% fixed to 3 decimal places`);