AngularJS: 在多值对象中找到最接近的值
AngularJS: find closest value in multiple-values object
我正在尝试学习一些 AngularJS 创建一个计算分布的 "simple" 数学工具。
我有一个数字数组,我设法获得了唯一值列表,其中包含对象中的出现次数和百分比(唯一数字作为键,出现次数、百分比和累进百分比作为值)。示例:
$scope.values = {"17" : [1, 0.02, 0.02],"18" : [6, 0.12, 0.14],"19" : [7, 0.14, 0.28],"20" : [9, 0.18, 0.46],"21" : [13, 0.26, 0.72], "22" : [4, 0.08, 0.8],"23" : [5, 0.1, 0.9],"24" : [1, 0.02, 0.92],"25" : [3, 0.06, 0.98],"26" : [1, 0.02, 1]}
唯一数是关键,3个值分别是出现次数、占总迭代次数的百分比和递进百分比。例如,数字 25 出现了 3 次,即 6% 的次数,并且包括 98% 的小于或等于 25 的数字。
问题
给定 "progressive percentage" 我需要获得最接近该百分比的值的键。因此,必须仅对第三个值执行搜索(如果有任何变化),应该确定最接近的值(select 两个等距值中的较大者),应该 return 键.
在上面的例子中:
- 如果我搜索 0.75,我应该得到 21,
- 如果我搜索 0.91,我应该得到 23。
有什么帮助吗?
这是我到目前为止的进展:
function nearest(num, ar) {
var i = 0,
closest, closestDiff, currentDiff;
for (i; i < ar.length; i++) {
if (closest) {
closestDiff = Math.abs(num - closest);
currentDiff = Math.abs(num - ar[i]);
if (currentDiff < closestDiff) {
closest = ar[i];
}
closestDiff = null;
currentDiff = null;
} else if (!closest) {
//give initial value
closest = ar[i];
}
}
function (pct) {
$scope.milestones = [];
var ms = $scope.getClosestNum(pct, $scope.values);
$scope.milestones.push(ms);
return $scope.milestones;
};
但是我的 HTML 中的 {{getMilestones(0.75)}}
没有 return 任何东西。
您需要创建一个如下所示的过滤器。
代码
app.filter('calculateThirdPercentile', function() {
return function(values) {
var returnValue = {};
if (angular.isArray(values) && values.length > 0) {
angular.forEach(values, function(value, index) {
returnValue[(Math.ceil(value[2]*10)*10)+"%"] = index;
});
}
return returnValue;
}
});
HTML
results | calculateThirdPercentile
控制器
$filter('calculateThirdPercentile')($scope.results);
希望对您有所帮助,谢谢。
我觉得
var ms = getClosestNum(0.75,$scope.values);
应该是
var ms = $scope.getClosestNum(0.75,$scope.values);
您已经在 $scope 对象上定义了该函数(这是典型的),因此应该在该对象上调用它。
您将 arr
作为 getClosest 函数的参数,但您在代码中引用了 ar
。当我更正此问题时似乎有效(以及在 html 中设置 ng-app="mcApp")。
我可能自己找到了解决方案。感谢@pankajparkar,我了解到我没有将值保存在适当的数组中。从那开始,我认为一个对象会更合适。因此,将数字收集到更多 "clean" 对象中,例如:
{"34":0.04,"35":0.1,"36":0.12,"37":0.14,"38":0.16,"39":0.18,"40":0.22,"41":0.28,"43":0.36,"44":0.38,"45":0.42,"46":0.48,"47":0.52,"48":0.6,"49":0.64,"50":0.7,"51":0.8,"52":0.88,"53":0.92,"54":0.94,"55":1}
我正在使用一个函数获取最接近的值,该函数识别立即低于和高于我正在寻找的值的两个数字,然后选择最接近的一个:
function findNearest(obj, value) {
for (var i in obj) {
if (value > obj[i]) prev = obj[i];
else if (value <= obj[i]) {
next = nums[i];
percentage = (Math.abs(value - prev) < Math.abs(next - value)) ? prev : next;
nearest = parseInt(Object.keys(obj).filter(function(key) {return obj[key] === percentage})[0]);
break;
}
}
return nearest;
}
干杯
我正在尝试学习一些 AngularJS 创建一个计算分布的 "simple" 数学工具。
我有一个数字数组,我设法获得了唯一值列表,其中包含对象中的出现次数和百分比(唯一数字作为键,出现次数、百分比和累进百分比作为值)。示例:
$scope.values = {"17" : [1, 0.02, 0.02],"18" : [6, 0.12, 0.14],"19" : [7, 0.14, 0.28],"20" : [9, 0.18, 0.46],"21" : [13, 0.26, 0.72], "22" : [4, 0.08, 0.8],"23" : [5, 0.1, 0.9],"24" : [1, 0.02, 0.92],"25" : [3, 0.06, 0.98],"26" : [1, 0.02, 1]}
唯一数是关键,3个值分别是出现次数、占总迭代次数的百分比和递进百分比。例如,数字 25 出现了 3 次,即 6% 的次数,并且包括 98% 的小于或等于 25 的数字。
问题
给定 "progressive percentage" 我需要获得最接近该百分比的值的键。因此,必须仅对第三个值执行搜索(如果有任何变化),应该确定最接近的值(select 两个等距值中的较大者),应该 return 键.
在上面的例子中:
- 如果我搜索 0.75,我应该得到 21,
- 如果我搜索 0.91,我应该得到 23。
有什么帮助吗?
这是我到目前为止的进展:
function nearest(num, ar) {
var i = 0,
closest, closestDiff, currentDiff;
for (i; i < ar.length; i++) {
if (closest) {
closestDiff = Math.abs(num - closest);
currentDiff = Math.abs(num - ar[i]);
if (currentDiff < closestDiff) {
closest = ar[i];
}
closestDiff = null;
currentDiff = null;
} else if (!closest) {
//give initial value
closest = ar[i];
}
}
function (pct) {
$scope.milestones = [];
var ms = $scope.getClosestNum(pct, $scope.values);
$scope.milestones.push(ms);
return $scope.milestones;
};
但是我的 HTML 中的 {{getMilestones(0.75)}}
没有 return 任何东西。
您需要创建一个如下所示的过滤器。
代码
app.filter('calculateThirdPercentile', function() {
return function(values) {
var returnValue = {};
if (angular.isArray(values) && values.length > 0) {
angular.forEach(values, function(value, index) {
returnValue[(Math.ceil(value[2]*10)*10)+"%"] = index;
});
}
return returnValue;
}
});
HTML
results | calculateThirdPercentile
控制器
$filter('calculateThirdPercentile')($scope.results);
希望对您有所帮助,谢谢。
我觉得
var ms = getClosestNum(0.75,$scope.values);
应该是
var ms = $scope.getClosestNum(0.75,$scope.values);
您已经在 $scope 对象上定义了该函数(这是典型的),因此应该在该对象上调用它。
您将 arr
作为 getClosest 函数的参数,但您在代码中引用了 ar
。当我更正此问题时似乎有效(以及在 html 中设置 ng-app="mcApp")。
我可能自己找到了解决方案。感谢@pankajparkar,我了解到我没有将值保存在适当的数组中。从那开始,我认为一个对象会更合适。因此,将数字收集到更多 "clean" 对象中,例如:
{"34":0.04,"35":0.1,"36":0.12,"37":0.14,"38":0.16,"39":0.18,"40":0.22,"41":0.28,"43":0.36,"44":0.38,"45":0.42,"46":0.48,"47":0.52,"48":0.6,"49":0.64,"50":0.7,"51":0.8,"52":0.88,"53":0.92,"54":0.94,"55":1}
我正在使用一个函数获取最接近的值,该函数识别立即低于和高于我正在寻找的值的两个数字,然后选择最接近的一个:
function findNearest(obj, value) {
for (var i in obj) {
if (value > obj[i]) prev = obj[i];
else if (value <= obj[i]) {
next = nums[i];
percentage = (Math.abs(value - prev) < Math.abs(next - value)) ? prev : next;
nearest = parseInt(Object.keys(obj).filter(function(key) {return obj[key] === percentage})[0]);
break;
}
}
return nearest;
}
干杯