Tengo una matriz de JavaScript que se crea dinámicamente en este formato.

[{prdName: "Testing2"},
{prdName: "Testing2,Testing3"},
{markets: "Testing5"},
{markets: "Testing5,Testing6"}]

Quiero eliminar la clave duplicada en el mapa de matriz anterior y convertirla a este formato.

 [ {prdName: "Testing2,Testing3"},
   {markets: "Testing5,Testing6"} ]

¿Podría decirme cómo lograr lo mismo? Estoy trabajando en una aplicación reactjs.

2
Rakesh Nallam 27 oct. 2017 a las 21:48

3 respuestas

La mejor respuesta

Supongo que desea conservar todas las entradas delimitadas por comas no duplicadas, no solo descartar todo, sino el último grupo como en las otras respuestas. (Entonces, por ejemplo, si la entrada fuera [{foo: "x"}, {foo:"x,y"}, {foo:"z"}], la salida debería ser [{foo: "x,y,z"}], no [{foo:"z"}]).

var rearrange = function(input) {
  var tmp = {}; // track keys and values as we find them
  for (obj of input) {
    var key = Object.keys(obj)[0]; // each input has one key
    tmp[key] = tmp[key] || {}; // initialize an empty object at that key in tmp if necessary
    var vals = obj[key].split(",");
    for (v of vals) {
      tmp[key][v.trim()] = 1; // keep each of the (trimmed) comma-delimited values, implicitly dropping duplicates
    }
  }

  // now convert the tmp object into an array:
  var output = [];
  for (k of Object.keys(tmp)) {
    var x = {};
    x[k] = Object.keys(tmp[k]).join(","); // merge the values back into a comma-separated string
    output.push(x);
  }
  return output;
}
console.log(rearrange([
  {prdName: "Testing2"},
  {prdName: "Testing2,Testing3"},
  {markets: "Testing5"},
  {markets: "Testing5,Testing6"}
]));

console.log(rearrange([
  {foo: "x"},
  {foo: "x,y"},
  {foo: "z"},
  {bar: "x,y,z"}
]));

Sin embargo, si todo lo que necesita es la última instancia de cada clave, esto está bastante cerca de una línea; solo use Object.assign para fusionar los objetos:

var rearrange = function(input) {
   var merged = Object.assign({},...input); // merges all input keys, overwriting early values with later ones
   
   // convert to array (if necessary. the "merged" object might be easier to work with...):
   var output=[];
   for (k of Object.keys(merged)) {
     var x = {};
     x[k] = merged[k];
     output.push(x)
   }
   return output;
}

console.log(rearrange([
    {prdName: "Testing2"},
    {prdName: "Testing2,Testing3"},
    {markets: "Testing5"},
    {markets: "Testing5,Testing6"}
]));
     
console.log(rearrange([{foo: "x"}, {foo:"x,y"}, {foo:"z"}]));
2
Daniel Beck 27 oct. 2017 a las 19:41

Con ES6, puede usar Map con Set para artículos únicos.

var array = [{ prdName: "Testing2" }, { prdName: "Testing2,Testing3" }, { markets: "Testing5" }, { markets: "Testing5,Testing6" }],
    map = new Map,
    result;

array.forEach(o => Object.keys(o).forEach(k => {
    if (!map.has(k)) {
        map.set(k, new Set);
    }
    o[k].split(',').forEach(s => map.get(k).add(s));
}));

result = [...map].map(([k, s]) => ({ [k]: [...s].join() }));

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
3
Nina Scholz 27 oct. 2017 a las 20:21
var lists =[{prdName: "Testing2"},

{prdName: "Testing2,Testing3"},

{markets: "Testing5"},

{markets: "Testing5,Testing6"}]

var newLists =[]
var keys = []
lists.forEach(item=>{
var key = Object.keys(item)[0];
if(keys.indexOf(key) === -1){
// first time the key is processed; it is stored in newLists
    keys.push(key);
    newLists.push(item);
  }
else {
// a duplicate key is found in the array
    let remove; 
    let values;
    newLists.forEach((item2,index) => {
        if (Object.keys(item2)[0] === key) {
// use of a set to have a union of values already stored for the key and the new values found for the same key using spread operator        
         values = new Set([...item2[key].split(","),...item[key].split(",")]);
            remove = index;
          }
    })
    newLists.splice(remove, 1);
    newLists.push({[key]:  Array.from(values).toString()})
  }
})

console.log(newLists);
1
edkeveked 28 oct. 2017 a las 14:45