使用1种模式从JSON合并对象

时间:2018-12-06 22:05:52

标签: javascript json

我需要按年份合并JSON中的对象。

我有这样的JSON:

[{
    Year: "2016",
    A: 666,
    B: "-"
},{
    Year: "2017",
    A: 1200,
    B: "-"
},{
    Year: "2016",
    B: 4585,
    A: "-"
},{
    Year: "2017",
    B: 5534,
    A: "-"
}]

如何制作这样的JSON?

[{
    Year: "2016",
    A: 666,
    B: 4585
},{
    Year: "2017",
    A: 1200,
    B: 5534
}]

这是我的原始功能:

function transformAtoBBeneficios(json) {

  function eliminate(arr, l) {
    return arr.filter(e => e !== l);
  };

  lista = [];
  for (i in json) {
    lista.push(json[i].Prestacion);
  };
  lista = lista.filter(function(item, pos) {
    return lista.indexOf(item) == pos;
  });
  console.log("lista");
  console.log(lista);
  var jsonb = "[";
  var fecha = "";
  for (var i in json) {
    //var dato = quitaEnters(json[i].Cantidad);
    var dato = json[i].Cantidad;
    if (i == 0) {
      var localList = lista;
      jsonb = jsonb.concat('{"Año": "');
      jsonb = jsonb.concat(json[i].Ano).concat('",');
      jsonb = jsonb.concat('"');
      jsonb = jsonb.concat(json[i].Prestacion.toString());
      jsonb = jsonb.concat('":');
      if (json[i].Cantidad === "")
        jsonb = jsonb.concat('"-"');
      else jsonb = jsonb.concat(dato);
      fecha = json[i].Ano;
      localList = eliminate(localList, json[i].Prestacion.toString());
    } else {
      if (fecha == json[i].Ano) {
        jsonb = jsonb.concat(",");
        jsonb = jsonb.concat('"');
        jsonb = jsonb.concat(json[i].Prestacion.toString());
        jsonb = jsonb.concat('":');
        if (json[i].Cantidad === "")
          jsonb = jsonb.concat('"-"');
        else jsonb = jsonb.concat(dato);

        localList = eliminate(localList, json[i].Prestacion.toString());
      } else {
        if (localList.length != 0) {
          for (var j in localList) {
            jsonb = jsonb.concat(",");
            jsonb = jsonb.concat('"');
            jsonb = jsonb.concat(localList[j].toString());
            jsonb = jsonb.concat('":"-"');
          };
        };
        var localList = lista;
        jsonb = jsonb.concat("},");
        jsonb = jsonb.concat('{"Año": "');
        jsonb = jsonb.concat(json[i].Ano).concat('",');
        jsonb = jsonb.concat('"');
        jsonb = jsonb.concat(json[i].Prestacion.toString());
        jsonb = jsonb.concat('":');
        if (json[i].Cantidad === "")
          jsonb = jsonb.concat('"-"');
        else jsonb = jsonb.concat(dato);
        fecha = json[i].Ano;
        localList = eliminate(localList, json[i].Prestacion.toString());
      }
    }

  }
  if (localList.length != 0) {
    for (var j in localList) {
      jsonb = jsonb.concat(",");
      jsonb = jsonb.concat('"');
      jsonb = jsonb.concat(localList[j].toString());
      jsonb = jsonb.concat('":"-"');
    };
  };
  jsonb = jsonb.concat("}]");
  if (jsonb == "[}]") {
    jsonb = "[]";
  };
  // return jsonb;
  return JSON.parse(jsonb);
};

var json_a = [{
  "Ano": 2016,
  "Prestacion": "DENTAL",
  "Cantidad": 2015
}, {
  "Ano": 2017,
  "Prestacion": "DENTAL",
  "Cantidad": 1200
}, {
  "Ano": 2018,
  "Prestacion": "DENTAL",
  "Cantidad": 1301
}, {
  "Ano": 2016,
  "Prestacion": "OFTALMOLOGICO",
  "Cantidad": 4585
}, {
  "Ano": 2017,
  "Prestacion": "OFTALMOLOGICO",
  "Cantidad": 5534
}, {
  "Ano": 2018,
  "Prestacion": "OFTALMOLOGICO",
  "Cantidad": 5446
}]

console.log("this is what I get: ");
console.log(transformAtoBBeneficios(json_a));

3 个答案:

答案 0 :(得分:0)

var a = [{
    Year: "2016",
    A: 666,
    B: "-"
},{
    Year: "2017",
    A: 1200,
    B: "-"
},{
    Year: "2016",
    B: 4585,
    A: "-"
},{
    Year: "2016",
    B: "-",
    A: "-"
},{
    Year: "2017",
    B: 5534,
    A: "-"
}];

// group the array by the 'Year' property
var b = a.reduce(function(a, cur) {
  (a[cur["Year"]] = a[cur["Year"]] || []).push({A:cur["A"],B:cur["B"]});
  return a;
}, {});

// select a non-empty value 
function choose(arr) { return arr.filter( a => a!="-" )[0]; }

var res = [];
for( var k in b ) {
  res.push( 
    {
      Year: k,
      A: choose( b[k].map( c => c["A"] ) ),
      B: choose( b[k].map( c => c["B"] ) )
    }
  );
}

//console.log(b);
console.log(res);

甚至更短

var a = [{
    Year: "2016",
    A: 666,
    B: "-"
},{
    Year: "2017",
    A: 1200,
    B: "-"
},{
    Year: "2016",
    B: 4585,
    A: "-"
},{
    Year: "2016",
    B: "-",
    A: "-"
},{
    Year: "2017",
    B: 5534,
    A: "-"
}];

// check non-empty value 
var non_empty = a => a != "-";
// group the array by the 'Year' property
var res = Object.entries( a.reduce( (a, cur) => {
    (a[cur["Year"]] = a[cur["Year"]] || []).push({A:cur["A"],B:cur["B"]});
    return a;
  }, {}) ).map( a => { return {
      Year: a[0],
      A: a[1].map( c => c["A"] ).filter( non_empty )[0] ,
      B: a[1].map( c => c["B"] ).filter( non_empty )[0]
    } } );


console.log(res);

答案 1 :(得分:0)

一种方法可能是首先从对象数组中过滤出找到“-”值的所有键/值对。然后,您将根据Year键的值将过滤后的对象组合成字典。要完成此过程,您将返回字典值以获取所需的数组:

const input = [{
  Year: "2016",
  A: 666,
  B: "-"
}, {
  Year: "2017",
  A: 1200,
  B: "-"
}, {
  Year: "2016",
  B: 4585,
  A: "-"
}, {
  Year: "2017",
  B: 5534,
  A: "-"
}];

const dictionary = input.map(item => (Object.entries(item).reduce((obj, [key,value]) => {

    // Create object and exclude key/value where value is "-"
    return (value === '-') ? obj : { ...obj, [key] : value }

  }, {})))
  .reduce((agg, item) => {

    // Group objects by Year key into dictionary
    const year = agg[item.Year] || {}

    agg[item.Year] = { ...year,
      ...item
    }

    return agg
  }, {})

// Extract values from dictionary to aquire required array result
const result = Object.values(dictionary)

console.log(result)

答案 2 :(得分:0)

我使用嵌套for循环可以得到您想要的结果。 for循环用于处理对象。解决方案的工作方式是,它获取b值='-'的年份,然后使用第二个for循环,查找匹配的年份,但b值!='-'。这意味着存在匹配项,因此请在两个匹配年份之间交换a和b值。

var results = [{
    Year: "2016",
    A: 666,
    B: "-"
},{
    Year: "2017",
    A: 1200,
    B: "-"
},{
    Year: "2016",
    B: 4585,
    A: "-"
},{
    Year: "2017",
    B: 5534,
    A: "-"
}];

for(var yearDetails in results){ // Look at all objects in the result
    if(results[yearDetails].B === '-'){ 
        // Look for the B result
        for (var yearMatch in results){
            // If the years match, and the B result != '-'
            if(results[yearMatch].Year === results[yearDetails].Year && results[yearMatch].B != '-'){
                // Set the a and b values now we have a match
                results[yearDetails].B = results[yearMatch].B;
                results[yearMatch].A = results[yearDetails].A
            }
        }
    }
}
console.log(JSON.stringify(results)); // So we can see the JSON result

希望这会有所帮助:)