0

I have a mapped an array object, now I need to get unique values from that array's children.

const arr=[
            {
              name: 'name1',
              functions:{
                0:{
                  name:'some1',
                  property: 'string'
                },
                1:{
                  name:'some1',
                  property: 'string'
                },
                2:{
                  name:'some3',
                  property: 'number'
                }
              }
            },
          ]


<div>
          {
              arr.map((item, index) => {
                  let ars=[]
                  //console.log(item.functions)
                  for(const key in item.functions){                
                    if(ars.indexOf(item.functions[key])>1){
                        ars.push(item.functions[key])
                    }
                  }
                  console.log(ars)
              return <div key={index}>
                <h2>{item.name}</h2>
                {
                    ars.map((i)=>(
                        <p>{i.name}</p>
                    ))
                }

              </div>
          })
          }
          </div>

I need to get values like this: some1 some3

So I need to get only one name from property string. And for number there is only one name.

Saban
  • 347
  • 1
  • 3
  • 17
  • Possible duplicate of [Filter unique values from an array of objects](https://stackoverflow.com/questions/43374112/filter-unique-values-from-an-array-of-objects) – Yannick K Jun 04 '19 at 19:31
  • I don't understand what is the expected output. Can you add to your question what you want the code to return? – Doug Jun 04 '19 at 19:33
  • Possible duplicate of [Get all unique values in a JavaScript array (remove duplicates)](https://stackoverflow.com/questions/1960473/get-all-unique-values-in-a-javascript-array-remove-duplicates) – 3limin4t0r Jun 04 '19 at 19:56

2 Answers2

1

You could create a Set for property. If a property hasn't been added yet, add the name for the property to the array.

const arr = [{
  name: 'name1',
  functions: {
    0: {
      name: 'some1',
      property: 'string'
    },
    1: {
      name: 'some2',
      property: 'string'
    },
    2: {
      name: 'some3',
      property: 'number'
    }
  }
}]

const propertySet = new Set,
      names = []

for (const { functions } of arr) {
  Object.values(functions).forEach(o => {
    if (!propertySet.has(o.property)) {
      names.push(o.name);
      propertySet.add(o.property)
    }
  })
}

console.log(names)
adiga
  • 34,372
  • 9
  • 61
  • 83
  • I need to get output like this: some1, some3 – Saban Jun 04 '19 at 19:36
  • @Saban This gives you an array of unique names. You can `map` through it and create the `div` as you're doing – adiga Jun 04 '19 at 19:37
  • @Saban why is `some2` not included in the expected output? – adiga Jun 04 '19 at 19:39
  • I need to filter array by property names, so I want to get some1 and not some2 because property name (string) is the same. – Saban Jun 04 '19 at 19:40
  • Not correct answer, he needs to print names based on unique properties. Since some2 and some3 has same property value only one should be in output – user8672473 Jun 04 '19 at 19:45
  • @user8672473 updated. OP's original question was unclear – adiga Jun 04 '19 at 19:48
  • @3limin4t0r If I understand correctly, OP doesn't want to get unique names. OP wants to get names for each unique `property`. Earlier version of OP's question had a different input. Check their comment in the thread. *"I want to get `some1` and not `some2` because `property` name is the same*" – adiga Jun 04 '19 at 19:59
  • @adiga Yep just saw it after looking at the code for a second time. So removed my other comment. – 3limin4t0r Jun 04 '19 at 20:00
0

If uniqueness based upon the string representation of the value of property is enough and the value of name is always truthy you can use the following code:

const arr = [{name: 'name1', functions: {0: {name: 'some1', property: 'string'}, 1: {name: 'some2', property: 'string'}, 2: {name: 'some3', property: 'number'}}}];

let lookup = {};
arr.forEach(obj => {
  Object.values(obj.functions).forEach(func => {
    lookup[func.property] || (lookup[func.property] = func.name);
  });
});

console.log(Object.values(lookup));

Note: This solution sees property: 123 and property: "123" as the same value, since the string representation is used. If the following is an option name: "", name: null, etc. then the first truthy name is used, if there is no truthy name present the last occurrence of name is used instead.

3limin4t0r
  • 19,353
  • 2
  • 31
  • 52