我有一个相当棘手的javascript数据操作问题,我正在努力。我有以下数据数组:
var myArray = [8, 13, 11, 17, 5, 13, 13];
我想将此数组映射到一个长度相等的数组中,其中新数组中的每个值等于数组在该点的前一个值之间的差值,以及下一个最低值上一个数组中的值。这很冗长,但是例如,我希望输出为:
var newArray = [3, 2, 3, 4, 5, 0, 0];
第一个元素中的<3>是(8-5),其中8是第一个时隙中数组的前一个值,5是前一个数组中的下一个最低值。
第二个元素中的2是(13 - 11),......等等。
我并不特别关心如何处理关系(例如原始数组中有2个值为13),只要将13的一个实例替换为(13 - 下一个最低值),并且13的所有其他实例都替换为零(基本上是13-13)。
谢谢!
答案 0 :(得分:3)
在map()中使用reduce()并使用indexOf()检查数字是否是第一个实例
var arr = [8, 13, 11, 17, 5, 13, 13];
var res = arr.map((n, i) => {
if (i !== arr.indexOf(n)) return 0;
return n - arr.reduce((a, c) => c < n && c > a ? c : a, 0);
})
console.log(JSON.stringify(res))/// [3, 2, 3, 4, 5, 0, 0]
替代方法,创建降序排序的唯一数组,然后在该数组中的下一个索引中查找数字
var arr = [8, 13, 11, 17, 5, 13, 13];
var sortedUniques = [...new Set(arr)].sort((a,b) => b-a);
var res = arr.map((n, i) => {
if (i !== arr.indexOf(n)) return 0;
var sortedIdx = sortedUniques.indexOf(n);
return n - ( sortedUniques[sortedIdx+1] || 0 );
})
console.log(JSON.stringify(res))/// [3, 2, 3, 4, 5, 0, 0]
答案 1 :(得分:1)
非常感谢@charlietfl帮助我理解有关重复项的部分:)一般来说,我想出了一个几乎相同的解决方案,除了使用Array.filter
和Math.max
而不是最小化一个Array.reduce
语句。
let myArray = [8, 13, 11, 17, 5, 13, 13],
cmpArray = myArray.concat([0]);
console.log(
myArray.map((value, index) => {
if(index !== myArray.indexOf(value)) return 0;
return value - Math.max(...cmpArray.filter(number => number < value));
})
);
&#13;
答案 2 :(得分:1)
您可以收集数组中的下一个值以及对象中的所有数组,并弹出值,直到获取所有值。
var array = [8, 13, 11, 17, 5, 13, 13],
temp = array
.slice()
.sort((a, b) => b - a)
.reduce(
(r, v, i, a) => ((r[v] = r[v] || []).push(v - (a[i + 1] || 0)), r),
Object.create(null)
),
result = array.map(v => temp[v].pop());
console.log(result);
&#13;
答案 3 :(得分:0)
这些方面的东西越来越接近我了。
let newArray = [];
myArray.forEach(function(d){
let temp = myArray.filter(val => val < d)
let maxRemVal = d3.max(temp)
maxRemVal = isNaN(maxRemVal) ? 0 : maxRemVal;
newArray.push(d - maxRemVal)
});