1

Having an array of objects like this one

   "medios":[  
      {  
         "Key":"1",
         "Text":"Cheque"
      },
      {  
         "Key":"2",
         "Text":"Tarjeta de Crédito"
      },
      {  
         "Key":"3",
         "Text":"Tarjeta de Crédito"
      },
      {  
         "Key":"4",
         "Text":"Tarjeta de Crédito"
      },
      {  
         "Key":"5",
         "Text":"Transferencia Bancaria"
      }
   ]

I need to be able to delete objects that has the same "Text" value (Tarjeta de Crédito, for example), until I only keep one of them. Any idea of how to achieve that?

I tried by using a loop over the array, but don't know how to delete the specific objects

kukiko11
  • 63
  • 8

6 Answers6

3

You can use reduce and dont add element when already present.

var medios = [{"Key": "1","Text": "Cheque"},{"Key": "2","Text": "Tarjeta de Crédito"},{"Key": "3","Text": "Tarjeta de Crédito"},{"Key": "4","Text": "Tarjeta de Crédito"},{"Key": "5","Text": "Transferencia Bancaria"}];

medios = medios.reduce((c, n) =>
  c.find(el => el.Text == n.Text) ? c : [...c, n], []);
console.log(medios);
Vanojx1
  • 5,574
  • 2
  • 23
  • 37
  • 1
    This solution is not efficient. It has a time complexity of *O(n²)* while it can be done in *O(n)*. – trincot Dec 27 '18 at 13:27
2

You could use a Map to key your data by Text so that you will only get unique entries. And then get the values from that map to rebuild your array again:

const obj = {"medios":[{ "Key":"1","Text":"Cheque"},{ "Key":"2","Text":"Tarjeta de Crédito"},{ "Key":"3","Text":"Tarjeta de Crédito"},{ "Key":"4","Text":"Tarjeta de Crédito"},{  "Key":"5","Text":"Transferencia Bancaria"}]};

obj.medios = Array.from(new Map(obj.medios.map(m => [m.Text, m])).values());

console.log(obj.medios);  
trincot
  • 317,000
  • 35
  • 244
  • 286
  • You are removing previous occurrencies as is, while removing dupes implies to keep the first key in which value is present – Mosè Raguzzini Dec 27 '18 at 13:20
  • 1
    @MosèRaguzzini, the OP did not specify that the first should be kept. Reading the question, there is no reason to believe the first is more important than the last. The question was only to delete objects that have the same Text, which this code is doing. – trincot Dec 27 '18 at 13:26
1

You can use the .filter() array method combined with a seperate array to track which texts we already have to create a new array containing only the wanted elements. The first entry will remain, so we expect key 2 to remain and key 3 and key 4 to be removed in the new array.

const data = {
  "medios":[  
    {  
     "Key":"1",
     "Text":"Cheque"
    },
    {  
     "Key":"2",
     "Text":"Tarjeta de Crédito"
    },
    {  
     "Key":"3",
     "Text":"Tarjeta de Crédito"
    },
    {  
     "Key":"4",
     "Text":"Tarjeta de Crédito"
    },
    {  
     "Key":"5",
     "Text":"Transferencia Bancaria"
    }
   ]
};

const seen = [];

const result = {
  "medios": data.medios.filter( entry => {
    const already_seen = seen.includes( entry.Text );
    if ( already_seen ) return false;
    else {
      seen.push( entry.Text );
      return true;
    }
  })
};

console.log( result );
Shilly
  • 8,511
  • 1
  • 18
  • 24
1

The most clean way to manage this IMHO is through simple lodash _.uniqBy() method:

const medios = [  
      {  
         "Key":"1",
         "Text":"Cheque"
      },
      {  
         "Key":"2",
         "Text":"Tarjeta de Crédito"
      },
      {  
         "Key":"3",
         "Text":"Tarjeta de Crédito"
      },
      {  
         "Key":"4",
         "Text":"Tarjeta de Crédito"
      },
      {  
         "Key":"5",
         "Text":"Transferencia Bancaria"
      }
   ]


console.log(_.uniqBy(medios, 'Text'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.min.js"></script>
Mosè Raguzzini
  • 15,399
  • 1
  • 31
  • 43
1

You can use _.uniqBy from lodash to keep it simple and clean in the following way

// medios = [{Key: 1, Text: '' }, {Key: 2, Text: '' } ]
medios = _.uniqBy(medios, 'Text');
Avi
  • 2,014
  • 1
  • 9
  • 21
  • Although some complies that lodash is an additional library, it makes code really more readable and this is a primary feature of modern coding. All other examples in the page will require comment to be understood < 10s – Mosè Raguzzini Dec 27 '18 at 13:24
  • 1
    @MosèRaguzzini you are right – Avi Dec 27 '18 at 13:28
0

You can use reduce . Inside reduce callback use find to check if the accumulator array contains an object with this text. find returns a Boolean value. If false then push the current object inside the accumulator

let medios = [{
    "Key": "1",
    "Text": "Cheque"
  },
  {
    "Key": "2",
    "Text": "Tarjeta de Crédito"
  },
  {
    "Key": "3",
    "Text": "Tarjeta de Crédito"
  },
  {
    "Key": "4",
    "Text": "Tarjeta de Crédito"
  },
  {
    "Key": "5",
    "Text": "Transferencia Bancaria"
  }
]
let k = medios.reduce((acc, curr) => {
  let findText = acc.find((item) => {
    return item.Text.toLowerCase() === curr.Text.toLowerCase();
  });
  if (!findText) {
    acc.push(curr)
  }
  return acc;
}, []);

console.log(k)
brk
  • 48,835
  • 10
  • 56
  • 78