从JSON字符串中删除重复的Date值

时间:2017-09-29 07:17:44

标签: javascript jquery arrays json morris.js

我正在研究莫里斯线图。我从服务中获得的json字符串是:

{"SDate": "2017-01-21", "A": 0, "B": 0, "C": 23},
{"SDate": "2017-01-21", "A": 10, "B": 0, "C": 0},
{"SDate": "2017-01-22", "A": 20, "B": 0, "C": 0},
{"SDate": "2017-01-23", "A": 30, "B": 0, "C": 67},
{"SDate": "2017-01-24", "A": 0, "B": 13, "C": 0},
{"SDate": "2017-01-25", "A": 70, "B": 0, "C": 0},
{"SDate": "2017-01-25", "A": 3, "B": 45, "C": 0},
{"SDate": "2017-01-26", "A": 50, "B": 0, "C": 0},
{"SDate": "2017-01-27", "A": 20, "B": 0, "C": 0},
{"SDate": "2017-01-28", "A": 80, "B": 0, "C": 0}

如您所见,前两行具有相同的日期,具有不同的值。 我想将两行合并为一个像

{"SDate": "2017-01-21", "A": 10, "B": 0, "C": 23},

同样,2017-01-25有2行,

{"SDate": "2017-01-25", "A": 70, "B": 0, "C": 0},
{"SDate": "2017-01-25", "A": 3, "B": 45, "C": 0},

我想要合并,如

{"SDate": "2017-01-25", "A": 73, "B": 45, "C": 0},

所以最终的JSON字符串就像

    {"SDate": "2017-01-21", "A": 10, "B": 0, "C": 23},
    {"SDate": "2017-01-22", "A": 20, "B": 0, "C": 0},
    {"SDate": "2017-01-23", "A": 30, "B": 0, "C": 67},
    {"SDate": "2017-01-24", "A": 0, "B": 13, "C": 0},
    {"SDate": "2017-01-25", "A": 73, "B": 45, "C": 0},
    {"SDate": "2017-01-26", "A": 50, "B": 0, "C": 0},
    {"SDate": "2017-01-27", "A": 20, "B": 0, "C": 0},
    {"SDate": "2017-01-28", "A": 80, "B": 0, "C": 0}

我知道理想情况下它应该在后端处理,但是我没有任何控制权,这需要使用javascript修复。 现在我正在尝试Sort and merge JSON keys with matching values的解决方案,但没有得到理想的结果。 请帮助

编辑1: 这里A,B和C不固定。 这可以是不同的集合。 像X,Y或Just W或任何东西。 例如

{"SDate": "2017-01-21", "X": 0, "Y": 0, "Z": 23},....,{"SDate": "2017-01-28", "X": 0, "Y": 0, "Z": 23}

或者

{"SDate": "2017-01-21", "W": 0, "B": 0, "V": 23},......,{"SDate": "2017-01-28", "W": 0, "B": 0, "V": 23},

和...... *对于特定字符串,集合将是相同的,但不一定是A,B和C

4 个答案:

答案 0 :(得分:2)

您可以通过将回调函数传递给数组中的每个项目来使用forEach方法。

解决方案是使用hash结构,以便仅保留唯一值,并找出重复行的总和。

let array=[{"SDate": "2017-01-21", "A": 0, "B": 0, "C": 23}, {"SDate": "2017-01-21", "A": 10, "B": 0, "C": 0}, {"SDate": "2017-01-22", "A": 20, "B": 0, "C": 0}, {"SDate": "2017-01-23", "A": 30, "B": 0, "C": 67}, {"SDate": "2017-01-24", "A": 0, "B": 13, "C": 0}, {"SDate": "2017-01-25", "A": 70, "B": 0, "C": 0}, {"SDate": "2017-01-25", "A": 3, "B": 45, "C": 0}, {"SDate": "2017-01-26", "A": 50, "B": 0, "C": 0}, {"SDate": "2017-01-27", "A": 20, "B": 0, "C": 0}, {"SDate": "2017-01-28", "A": 80, "B": 0, "C": 0}]
let result=[];
array.forEach(function (item) {
    if (!this[item.SDate]) {
        this[item.SDate] = { SDate: item.SDate };
        Object.keys(item).slice(1).forEach(function(key){
          this[item.SDate][key]=0;
        });
        result.push(this[item.SDate]);
    }
    Object.keys(item).slice(1).forEach(function(key){
          this[item.SDate][key]+=item[key];
    });
});
console.log(result);

答案 1 :(得分:1)

您可以通过以下方式执行此操作

let arr = [
{"SDate": "2017-01-21", "A": 0, "B": 0, "C": 23},
{"SDate": "2017-01-21", "A": 10, "B": 0, "C": 0},
{"SDate": "2017-01-22", "A": 20, "B": 0, "C": 0},
{"SDate": "2017-01-23", "A": 30, "B": 0, "C": 67},
{"SDate": "2017-01-24", "A": 0, "B": 13, "C": 0},
{"SDate": "2017-01-25", "A": 70, "B": 0, "C": 0},
{"SDate": "2017-01-25", "A": 3, "B": 45, "C": 0},
{"SDate": "2017-01-26", "A": 50, "B": 0, "C": 0},
{"SDate": "2017-01-27", "A": 20, "B": 0, "C": 0},
{"SDate": "2017-01-28", "A": 80, "B": 0, "C": 0}
];

arr = arr.sort((a, b) => {
        if(a.SDate < b.SDate)
            return -1;
        if(a.SDate > b.SDate)
            return 1;
        return 0;
}).reduce((a, b) => {
    if(a.length == 0){
        a.push(b);
    }
    else if(a[a.length-1].SDate != b.SDate){
        a.push(b);
    }
    else {
        a[a.length-1].A += b.A;
        a[a.length-1].B += b.B;
        a[a.length-1].C += b.C;
    }
    return a;
}, [])

console.log(arr);

答案 2 :(得分:1)

你有不同的方法......

var yourData = [
  {"SDate": "2017-01-21", "A": 0, "B": 0, "C": 23},
  {"SDate": "2017-01-21", "A": 10, "B": 0, "C": 0},
  {"SDate": "2017-01-22", "A": 20, "B": 0, "C": 0},
  {"SDate": "2017-01-23", "A": 30, "B": 0, "C": 67},
  {"SDate": "2017-01-24", "A": 0, "B": 13, "C": 0},
  {"SDate": "2017-01-25", "A": 70, "B": 0, "C": 0},
  {"SDate": "2017-01-25", "A": 3, "B": 45, "C": 0},
  {"SDate": "2017-01-26", "A": 50, "B": 0, "C": 0},
  {"SDate": "2017-01-27", "A": 20, "B": 0, "C": 0},
  {"SDate": "2017-01-28", "A": 80, "B": 0, "C": 0}
];

var newData = {};

// Create an object using dates as indexes, so we can find it on each loop.
$.each(yourData,function(id,value) {

    if (!newData[value['SDate']])
        newData[value['SDate']] = {"SDate": value.SDate, "A": 0, "B": 0, "C": 0};

    newData[value['SDate']]["A"] += value.A;
    newData[value['SDate']]["B"] += value.B;
    newData[value['SDate']]["C"] += value.C;
});

// Remove indexes and get the desired array of values.
newData = $.map(newData,function(value,index) {
  return value;
});

console.log(newData);

我希望它有所帮助

答案 3 :(得分:1)

你可以采用动态方法,使用哈希表和键的变量,你喜欢分组。

所有属性的其余部分用于求和。

var data = [{ SDate: "2017-01-21", A: 0, B: 0, C: 23 }, { SDate: "2017-01-21", A: 10, B: 0, C: 0 }, { SDate: "2017-01-22", A: 20, B: 0, C: 0 }, { SDate: "2017-01-23", A: 30, B: 0, C: 67 }, { SDate: "2017-01-24", A: 0, B: 13, C: 0 }, { SDate: "2017-01-25", A: 70, B: 0, C: 0 }, { SDate: "2017-01-25", A: 3, B: 45, C: 0 }, { SDate: "2017-01-26", A: 50, B: 0, C: 0 }, { SDate: "2017-01-27", A: 20, B: 0, C: 0 }, { SDate: "2017-01-28", A: 80, B: 0, C: 0 }],
    groupBy = 'SDate',
    hash = Object.create(null),
    grouped = [];

data.forEach(function (o) {
    if (!hash[o[groupBy]]) {
        hash[o[groupBy]] = {};
        hash[o[groupBy]][groupBy] = o[groupBy];
        grouped.push(hash[o[groupBy]]);
    }
    Object.keys(o).forEach(function (k) {
        if (k === groupBy) {
            return;
        }
        hash[o[groupBy]][k] = (hash[o[groupBy]][k] || 0) + o[k];
    });
});
    
console.log(grouped);
.as-console-wrapper { max-height: 100% !important; top: 0; }