英文:
How to simplify an array by removing numbers that are close to each other in javascript
问题
我有一个包含一些数字的数组:
[0, 0.1, 0.2, 0.3, 0.6, 0.8, 1]
如何删除彼此接近且小于或等于 0.2
阈值的数字,并将这些值的平均值代替,使得上述数组变为:
[0.2, 0.8]
0.2
是因为 [0, 0.1, 0.2, 0.3]
彼此接近,所以它们变成了 (0 + 0.1 + 0.2 + 0.3) / 4 = 0.2
0.8
是因为 [0.6, 0.8, 1]
彼此接近,所以它们变成了 (0.6 + 0.8 + 1) / 2 = 0.8
英文:
I have an array with some numbers
[0, 0.1, 0.2, 0.3, 0.6, 0.8, 1]
how do I remove numbers that are close to each other less than or equal to 0.2
threshold and put the average of those values instead,
so the above array becomes
[0.2, 0.8]
0.2
because [0, 0.1, 0.2, 0.3]
are close to each other so they become (0 + 0.1 + 0.2 + 0.3) / 4 = 0.2
0.8
because [0.6, 0.8, 1]
are close to each other so they become (0.6, 0.8, 1) / 2 = 0.8
答案1
得分: 1
你可以通过迭代数组的每个元素并保持一个临时的close
数组来实现这个。如果close
为空,或者当前元素与close
中的最后一个元素的差小于阈值,那么你可以将它添加到close
中。如果不是,那么对close
求平均值并将其添加到输出数组中。注意,浮点数运算在这里会有些奇怪,你可以使用这个四舍五入的技巧。
const fixFloat = n => parseFloat(n.toPrecision(12))
function average(arr) {
let sum = 0;
for (const el of arr) sum += el;
return fixFloat(sum / arr.length);
}
function closeRemove(arr, threshold) {
arr = [...arr].sort()
const res = [];
let close = [];
for (let i = 0; i < arr.length; i++) {
const diff = fixFloat(arr[i] - close[close.length-1]);
if (close.length == 0 || diff <= threshold) {
close.push(arr[i])
} else {
res.push(average(close));
close = [arr[i]];
}
}
res.push(average(close));
return res;
}
const arr = [0, 0.1, 0.2, 0.3, 0.6, 0.8, 1];
console.log(closeRemove(arr, 0.2));
请注意,在你的问题中,数字0
、0.1
、0.2
、0.3
的差都小于0.2
,所以它们应该被平均在一起。它们的平均值是1.5
,而不是2
。
英文:
You could do this by iterating over every element of the array and keeping a temporary close
array. If close
is empty, or the current element and the last element in close
's difference is less than the threshold, then you can add it to close
. If not, then average close
and add it to the output array. Note that floating point math gets a bit weird here, you can use this rounding trick.
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-js -->
const fixFloat = n => parseFloat(n.toPrecision(12))
function average(arr) {
let sum = 0;
for (const el of arr) sum += el;
return fixFloat(sum / arr.length);
}
function closeRemove(arr, threshold) {
arr = [...arr].sort()
const res = [];
let close = [];
for (let i = 0; i < arr.length; i++) {
const diff = fixFloat(arr[i] - close[close.length-1]);
if (close.length == 0 || diff <= threshold) {
close.push(arr[i])
} else {
res.push(average(close));
close = [arr[i]];
}
}
res.push(average(close));
return res;
}
const arr = [0, 0.1, 0.2, 0.3, 0.6, 0.8, 1];
console.log(closeRemove(arr, 0.2));
<!-- end snippet -->
Note that in your question, the numbers 0
, 0.1
, 0.2
, 0.3
all have a difference of less than 0.2
, so they should be averaged together. Their average is 1.5
, not 2
.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论