-1

I know that some would mark this is a duplicate, but in my case (and my limited knowledge) i still haven't found any similar example which i can relate to.. Therefore i say sorry upfront :)

It's pretty straight forward for an experienced JS dev i assume..

I just cannot figure out how to match on a arrays property :

 if (!uniqueEnts.includes(ent.entity)) {  // how do i match on uniqueEnts.entityName ?

Current approach results in too many hits in the new list, and the check (look above) doesn't provide with the correct check against uniqueEnts.entityName

JSON Input : enter image description here

Desired output : new list (uniqueEntities) with the following two properties

  • entityName (unique)
  • entityColor (randomly generated)

Code :

 uniqueEntities() {
        let uniqueEnts = []
        this.nluDataUnfiltered.forEach(function (i) {
            i.entities.forEach(function (ent) {
                if (!uniqueEnts.includes(ent.entity)) {
                    let obj = {
                        entityName: ent.entity,
                        entityColor: Util.getRandomColor()
                    }
                    uniqueEnts.push(obj)
                    obj = null
                }
            })
        })
        return _uniqueEnts.entityName.sort().value()
        // earlier tryout --> return _(uniq(uniqueEnts.entityName)).sort().value()
    },

UPDATED WITH LATEST TRYOUT :

uniqueEntities() {
        let uniqueEntityObj
        var uniqueEntity = Array.from(new Set( data.map(el => this.nluDataUnfiltered.entities[0].entity) ));
            uniqueEntityObj = uniqueEntity.map(el => { 
                entityName:el,  
                entityColor: Util.getRandomColor() 
            });
        return uniqueEntityObj
    },

Error : enter image description here

Terje Nygård
  • 1,233
  • 6
  • 25
  • 48
  • Possible duplicate of [Most elegant way to create a list of unique items in JavaScript](https://stackoverflow.com/questions/11688692/most-elegant-way-to-create-a-list-of-unique-items-in-javascript) – user3483203 Feb 19 '18 at 20:58
  • 1
    Please update the question with the input, expected output and issue with the approach you have taken. – void Feb 19 '18 at 20:59
  • coming right away... – Terje Nygård Feb 19 '18 at 21:00
  • About your error in `map`: [ECMAScript6 arrow function that returns an object](https://stackoverflow.com/questions/28770415/ecmascript6-arrow-function-that-returns-an-object/28770578) – yuriy636 Feb 19 '18 at 21:47
  • The problem with your code is that you are checking if the `uniqueEnts` `array` includes the `string` contained in `ent.entity`, but `uniqueEnts` is an `array` of `objects`, it doesn't contain any `string`. So, for this reason, you got duplicates. – ElChiniNet Feb 19 '18 at 23:39

2 Answers2

2

The steps could be to get all the unique entity from your array. I am doing this using sets as sets can only store unique values. And then using .map again to convert it to array of objects.

var setDataRaw = this.nluDataUnfiltered.map(
  (el) => {
    if (el.entities.length == 0)
      return [];

    return el.entities.map(
      (_entity) => {
        return _entity.entity;
      }
    )
  });

var setData = [].concat.apply([], setDataRaw);
var uniqueEntity = Array.from(new Set(setData));

var uniqueEntityObj = uniqueEntity.map((el) => {
  return {
    entityName: el,
    entityColor: Util.getRandomColor()
  };
});
void
  • 36,090
  • 8
  • 62
  • 107
  • updated the question with your approach, and error message.. Care to take a look ? (bm : entityName and entityColor is _not_ part of the input data.. – Terje Nygård Feb 19 '18 at 21:29
  • @TerjeNygård see the updated answer. Your `Util.getRandomColor()` works fine right? – void Feb 19 '18 at 21:33
  • You can change the property names to whatever required. – void Feb 19 '18 at 21:33
  • getRandomColor works yes.. looking through updated answer.. *sec*. – Terje Nygård Feb 19 '18 at 21:34
  • seems like my head is struggling with data.map .. should it be : var uniqueEntity = Array.from(new Set( this.nluDataUnfiltered.map(el => this.nluDataUnfiltered.entities[0].entity) )); – Terje Nygård Feb 19 '18 at 21:37
  • Not exactly but yea mine had a little issue. See the updated answer! Lets see if this works. Debugging a non working snippet gets really tough :( – void Feb 19 '18 at 21:41
  • getting an evaluation error on this unfortunately :) Care to give me a second in chat ? – Terje Nygård Feb 19 '18 at 21:41
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/165439/discussion-between-void-and-terje-nygard). – void Feb 19 '18 at 21:42
  • Big kudos and digital beer for @void!.. Thanks a lot for the time-consuming, and great help ! – Terje Nygård Feb 19 '18 at 22:17
  • +1 for a nice solution using `Sets`. Just an observation, I think that the condition checking if the length of the `array` is `0` could be removed. If the `array` is empty the `map` method should return an empty `array`. – ElChiniNet Feb 19 '18 at 23:31
1

Following the same @void's idea of creating an Array of unique entities from a Set, here you have his same code but using the spread operator and array reduce to create the full Array of entities.

let uniqueEntityObj = Array.from(
    new Set(
        nluDataUnfiltered.reduce(
            (a, o) => (
                [...a, ...(o.entities.map(so => so.entity))]
            ),
            []
        )
    )
).map(p => ( {entityName: p, entityColor: Util.getRandomColor()} ));

Here you have the compact (and less readable) version:

let uniqueEntityObj = Array.from(new Set(nluDataUnfiltered.reduce((a, o) => ([...a, ...(o.entities.map(so => so.entity))]), []))).map(p => ({entityName: p, entityColor: Util.getRandomColor() }));
ElChiniNet
  • 2,778
  • 2
  • 19
  • 27
  • Thanks for your add @ElChiniNet :) Just a question of curiousity... how on _earth_ have you learned this ? :) – Terje Nygård Feb 19 '18 at 23:57
  • @TerjeNygård, it is no hard to learn. You can start [here](http://es6-features.org/). Anyway, my solution is more [functional](https://en.wikipedia.org/wiki/Functional_programming) but more [complex](https://en.wikipedia.org/wiki/Time_complexity). Your solution is OK and less complex, you just needed to change [some things](https://jsfiddle.net/elchininet/xcmkvs8k/). – ElChiniNet Feb 20 '18 at 08:24