javascript对应的几个数组减少/汇总

javascript several corresponding array reducing/sumup

本文关键字:数组 几个 汇总 javascript      更新时间:2023-09-26

减少这些数组的最干净的方法是什么?

data = {
    id: [1, 1, 1, 3, 3, 4, 5, 5, 5, ...]
    v: [10,10,10, 5, 10 ...]
}

对于每个id都有一个对应的v。我想要的是为每个id加上v。在这个例子中,结果应该是

data = {
    id: [1, 3, 4, 5, ...]
    v: [30, 15, ...]
}

我会选择Array.prototype.reduce(),简单优雅的解决方案

var ids = [1, 1, 1, 3, 3, 3, 3, 4, 5, 6, 6, 6],
  v = [10, 10, 10, 5, 10, 10, 10, 404, 505, 600, 60, 6],
  data = {};
data.v = [];
data.ids = ids.reduce(function(a, b, index) {
  if (a.indexOf(b) < 0) a.push(b);
  if (!data.v[a.indexOf(b)]) data.v[a.indexOf(b)] = 0;
  data.v[a.indexOf(b)] += v[index];
  return a;
}, []);

https://jsfiddle.net/2ssbngLr/

在给定两个等长数组的情况下,一种方法是映射/减少它们:

const ids = [1, 1, 1, 3, 3];
const vs = [10,10,10,5,10];
const reduced = ids
.map((val, i) => ({ id: val, value: vs[i] }))
.reduce((agg, next) => {
    agg[next.id] = (agg[next.id] || 0) + next.value;
    return agg;
}, {});
console.log(reduced);
// Object {1: 30, 3: 15}

工作示例:https://jsfiddle.net/h1o5rker/1/

我认为使用reduce可以实现

 var data = {
   id: [1, 1, 1, 3, 3],
   v: [10, 10, 10, 5, 10]
 }
 var sumsObjs = data.v.reduce(function(sum, val, index) {
   var id = data.id[index];
   if (sum[id] !== undefined) {
     sum[id] = sum[id] + val;
   } else {
     sum[id] = val;
   }
   return sum;
 }, {});
 console.log(sumsObjs);
<script src="https://getfirebug.com/firebug-lite-debug.js"></script>

var data={
  id: [1,1,1,10,123,4531],
  v:[123,123,53,223,11,11,11]
},
 _v = data.v, vinit;
document.write(data.v+'<br>');
 for(var i=0;i<_v.length;i++){
  vinit = _v[i];
  for(var j=i+1; j<=_v.length;j++){
    if(_v[j]===vinit){
     delete _v[j];
    }
  }
 };
document.write(data.v);

var data={
  id: [1,1,1,10,123,4531],
  v:[123,123,53,223,11,11,11,...]
},
 _v = data.v, vinit;
 for(var i=0;i<_v.length;i++){
  vinit = _v[i];
  for(var j=i+1; j<=_v.length;j++){
    if(_v[j]===vinit){
     delete _v[j];
    }
  }
 }

上面的代码只针对v,但您也可以通过引入更多变量来同时减少id的重复元素

在这个片段中,您可以看到第二行中有额外的逗号,这表明这些元素已被删除

如果id总是有序的,那么一个简单的for循环就可以解决它。不需要变得过于复杂。

data = {
  id: [1, 1, 1, 3, 3, 4, 5, 5, 5],
  v: [10, 10, 10, 5, 10, 1, 2, 3, 4]
};
var result = {
  id: [],
  v: []
};
(function() {
  var ids = data.id,
    vals = data.v,
    lastId = ids[0],
    runningTotal = vals[0];
  for (var i = 1; i < ids.length; i++) {
    if (lastId === ids[i]) {
        runningTotal += vals[i];
    }
    if (lastId !== ids[i] || i + 1 === ids.length) {
      result.id.push(lastId);
      result.v.push(runningTotal);
      lastId = ids[i];
      runningTotal = vals[i];
    }
  }
}());
console.log(result);

到目前为止,有些人已经发布了一些不错的解决方案,但我还没有真正看到一个能满足需求的解决方案。这里有一个接受您的特定对象并返回相同格式的对象,但满足您的要求并减少了。

// Your data object
data = {
    id: [1, 1, 1, 3, 3],
    v: [10,10,10, 5, 10]
}
// Assuming obj consists of `id` and `v`
function reduce(obj){
  // We create our reduced object 
  var reducedObj = {
    id: [],
    v: []
  }
  // Next we create a hash map to store keys and values
  var map = {};
  for(var i=0; i<obj.id.length; ++i){
    // If this key doesn't exist, create it and give it a value
    if(typeof map[parseInt(obj.id[i])] === 'undefined'){
      map[parseInt(obj.id[i])] = 0;
    }
    // Sum all of the values together for each key
    map[parseInt(obj.id[i])] += parseInt(obj.v[i]);
  }
  // Now we map back our hashmap to our reduced object
  for(var ele in map){
    reducedObj.id.push(ele);
    reducedObj.v.push(map[ele]);
  }
  // Return our new reduced object
  return reducedObj;
}
var myReducedObject = reduce(data);
console.log(myReducedObject);

工作Fiddle

这是带Array.prototype.reduce()的有序id的解决方案。

var data = {
        id: [1, 1, 1, 3, 3, 4, 5, 5, 5],
        v: [10, 10, 10, 5, 10, 7, 8, 10, 13]
    },
    result = { id: [], v: [] };
data.id.reduce(function (r, a, i) {
    if (r === a) {
        result.v[result.v.length - 1] += data.v[i];
    } else {
        result.id.push(a);
        result.v.push(data.v[i]);
    }
    return a;
}, -1);
document.write('<pre>' + JSON.stringify(result, 0, 4) + '</pre>');

或现场版本

var data = {
    id: [1, 1, 1, 3, 3, 4, 5, 5, 5],
    v: [10, 10, 10, 5, 10, 7, 8, 10, 13]
};
void function (d) {
    var i = 1;
    while (i < d.id.length) {
        if (d.id[i - 1] === d.id[i]) {
            d.id.splice(i, 1);
            d.v[i - 1] += d.v.splice(i, 1)[0];
            continue;
        }
        i++;
    }
}(data);
document.write('<pre>' + JSON.stringify(data, 0, 4) + '</pre>');