1

I'm working on a function that gets an array of objects from an API, in those objects their is an array of tags, I want to return all the tags of those objects to populate a select field in my mark up. This is what I got so far and it's starting to get a bit confusing with all the maps I'm doing, its also returning the values but its returning them the same length of the original array of objects and get rid of any duplicates. What I'm I doing wrong or is their a better way to do this, and I'm using lodash?

renderOptions(){
        let dataRef = this.props.designs.items,
            tagArray = [],
            newArr = []
        return(_.map(dataRef, (design) => {
            let tags = design.tags,
                finalArr 
            return(_.map(tags, (tag) =>{
                    tagArray.push(tag)
                    newArr = [ ...new Set(tagArray) ]
                    return(_.map(newArr, (item) => {
                        console.log(item)
                        return( <li><h1>{item}</h1></li> )
                    }))
                })
            )
        }))
     }
4
  • are you using lodash or underscore? Commented Sep 8, 2016 at 15:02
  • Sorry did I miss that about lodash? I don't understand about duplicates: you do or you don't want duplicates? I'm guessing you don't but just to confirm... Commented Sep 8, 2016 at 15:20
  • Yeah, I'm trying to get rid of duplicates, using the ES6 new Set syntax Commented Sep 8, 2016 at 15:25
  • You're re-instantiating newArr on every iteration during the second map. Are you perhaps intending to use concat? ie: newArr = newArr.concat(...new Set(tagArray)); Commented Sep 8, 2016 at 15:26

2 Answers 2

1

Using reduce I have made the code more succinct, there's a working version on JS Bin. You'll have to adapt that to put in your framework (is it React?).

A good tip is to look out for the return types for lodash methods. The method reduce returns an array so this means we don't need to create a temporary array to hold our value and is assigned straight away to tags_array.

// assuming your data is something like this...
var objects = [
  {
    name: 'a',
    tags: ['a', 'b', 'c']
  },
  {
    name: 'b',
    tags: ['b', 'c', 'd']
  },
  {
    name: 'c',
    tags: ['a', 'c', 'd', 'e']
  }
]


var tags_array = _.uniq(                // returns a unique array.
  _.reduce(objects, function(i, o){     // iterates through objects and
    return o.tags;                      // returns o.tags each time
  })
);

console.log(tags_array);
// #=> ["a", "c", "d", "e"] 

So your function might work something like this, I'm guessing:

renderOptions(){
    let dataRef = this.props.designs.items;
    var tags_array = _.uniq(                // returns unique.
      _.reduce(dataRef, function(i, o){     // iterates through objects and
        return o.tags;                      // returns o.tags each time
      })
    );
    return tags_array;
 }

Then you could iterate through the array in your view, or adapt the renderOptions function to return the li html elements instead.

The reduce method can be used too as Palermo mentioned below:

let tags_array = objects.reduce((i, o) => { return o.tags; });

so lodash is not needed.

Sign up to request clarification or add additional context in comments.

1 Comment

I completely forgot about reduce, this is a very nice solution. Thanks!
0

You don't even need lodash to do this. Here is an even cleaner way to do this

let tags_array = dataRef.reduce((i, o) => { return o.tags; });

1 Comment

Brilliant, I'll add to answer

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.