Valori distincte dintr-o matrice cu obiecte

Am o variabila de forma:

[ { Data: 2019, IdJudet: "09,18" }, { Data: 2019, IdJudet: "09,18, 20, 03" }, { Data: 2019, IdJudet: "09" }, { Data: 2019, IdJudet: null } ]

Incerc sa fac un array cu valorile unice de la IdJudet, ex: [ “03”, “09”, “18”, “30” ].
Am incercat cu collect(variabila).pluck(‘IdJudet’) insa nu o pot procesa mai departe. In consola primesc ceva de genul: n {items: Array(12)}

Multumesc!

const ids = variabila
   // get only the required field
  .map((item) => item.IdJudet)
   // filter away null values and empty strings
  .filter(Boolean)
   // split by comma and trim spaces
  .map((IdJudet) => IdJudet.split(",").map(id => id.trim()))
   // reduce arrays to your result
  .reduce((result, ids) => result.concat(ids), [])

// remove duplicates
const result = ids.filter((id, i) => ids.indexOf(id) === i)
7 Likes

Daca ai volum mare de date ai iesi mai bine cu varianta clasica. Nu e la fel de frumoasa dar ar trebui sa fie de cateva ori mai rapida si sa foloseasca mai putina memorie.
LE:
https://jsperf.com/js-prf/1

let arr = [ { Data: 2019, IdJudet: "09,18" }, { Data: 2019, IdJudet: "09,18, 20, 03" }, { Data: 2019, IdJudet: "09" }, { Data: 2019, IdJudet: null } ];

const helper = {};
for (let i = 0; i < arr.length; i++) {

    if (arr[i].IdJudet === null || arr[i].IdJudet === undefined || arr[i].IdJudet === '' || arr[i].Data === null) continue;
    if (!helper[arr[i].Data]) helper[arr[i].Data] = {};

    helper[arr[i].Data].IdJudet = helper[arr[i].Data].IdJudet || '';
    (i === 0) ? helper[arr[i].Data].IdJudet += arr[i].IdJudet : helper[arr[i].Data].IdJudet += ',' + arr[i].IdJudet;

};


Object.keys(helper).forEach(function(key) {
  helper[key].IdJudet = [...new Set(helper[key].IdJudet.split(/\s*,\s*/))];
});

//{"2019":{"IdJudet":["09","18","20","03"]}}
1 Like
const idMap = arr.reduce((acc, item) => {
  if(item && item.IdJudet && item.IdJudet.trim()) {
    const split = item.IdJudet.split(',');

    split.forEach(item => {
      const trimmed = item.trim();
      
      if(!acc[trimmed]) {
       acc[trimmed] = true; 
      }
    });
  }

  return acc;
}, {});

const judete = Object.keys(idMap);

3 Likes

Omu e clar la un nivel la care nu se descurca cu functiile de baza din JS, de ce postam optimizari premature fara explicatii? Ce invata?

Give a man a fish , and you feed him for a day. Teach a man to fish , and you feed him for a lifetime.

3 Likes

O alta abordare

const data = [ { Data: 2019, IdJudet: "09,18" },
                { Data: 2019, IdJudet: "09,18, 20, 03" },
                { Data: 2019, IdJudet: "09" },
                { Data: 2019, IdJudet: null }
 
            ]

//filterz pt a elimina judetul null si unesc dupa IdJudets plus normalizez spatii;e
const county = data.filter(j => j.IdJudet != null).map(j => j.IdJudet).join(',').replace(/\s+/g, '')

//creez un array cu un set care nu permite valori duplicate
const noDuplicatesCounties = Array.from(new Set(county.split(',')))

console.log(noDuplicatesCounties)

//["09", "18", "20", "03"]

Ce parere aveti ?
Js-ul nu este limbajul meu de lucru.

Output-ul l-am considerat fiind sub aceasta forma:

Incerc sa fac un array cu valorile unice de la IdJudet, ex: [ “03”, “09”, “18”, “30” ].

O alta abordare care merge pe ceea ce a postat op-ul esste folosirea bibliotecii Underscore

In acest caz, problema se simplifica fiind necesara studierea documentatiei

let _ = require('underscore');
let data = [ { Data: 2019, IdJudet: "09,18" }, { Data: 2019, IdJudet: "09,18, 20, 03" }, { Data: 2019, IdJudet: "09" }, { Data: 2019, IdJudet: null } ]
 
let collectedData = _.collect(data)
let counties = _.pluck(collectedData, 'IdJudet').join(',').replace(/\s+/g, '')
let noDupesCounties = _.uniq(counties.split(',').filter(Boolean))
console.log(noDupesCounties)

//Array(4) ["09", "18", "20", "03"]

Cu functia _.filter

let data = [ { Data: 2019, IdJudet: "09,18" }, { Data: 2019, IdJudet: "09,18, 20, 03" }, { Data: 2019, IdJudet: "09" }, { Data: 2019, IdJudet: null } ]
 
let collectedData = _.collect(data)
let counties = _.pluck(collectedData, 'IdJudet').join(',').replace(/\s+/g, '')
let noDupesCounties = _.uniq(counties.split(','))
let noDupesCounties1 = _.filter(noDupesCounties, function(c){
    return c !== ""
})
console.log(noDupesCounties1)

https://underscorejs.org/#collections

Personal recomand prima varianta din discutie. Este mult mai clean si usor de inteles :slight_smile:

1 Like

:stuck_out_tongue: - aveam o operatie in plus, am presupus ca vor fi mai multe varianta de Data

const helper = {};
for (let i = 0; i < arr.length; i++) {

    if ( !arr[i].IdJudet || !arr[i].Data ) continue;

    const judete = arr[i].IdJudet.split(/\s*,\s*/);
    for (let j = 0; j < judete.length; j++) {
        if (!helper[judete[j]]) {
            helper[judete[j]] = true;
        }
    }
};

Object.keys(helper);

//output: [ '18', '20', '32', '64', '96', '09', '03', '04' ]

M-am inspirat la tine sa-l fac mai curat oricum. Thanks!

Wait, what?
Acum vad ca din testul tau varianta mea este cea mai lenta.
In testul meu ce a iesit atunci? :expressionless:

Nevermind. Acum am vazut ca nu este cel mai lent ci este doar numele testului…
Dar nici macar nu returna ce trebuie, concatenarea este gresita. Plus ca acea concatenare ocupa multa memorie daca sunt multe duplicate.