user7131971
user7131971

Reputation: 13

Mapping and Reducing an Array within an Array of Objects in Javascript

I'd appreciate any advice on the below. I need to extract the keywords from the array within an array of objects below, and reduce them to show all keywords without repetition.

My data JSON object is below:

[
  {
    "word":"Cat",
    "answer":"A type of feline",
    "keywords": ["pet", "mouse-catcher"]
  },
  {
    "word":"Dog",
    "answer":"A type of canine",
    "keywords": ["pet", "cat-catcher"]
  },
]

My JS code is below:

let keywordList = data.map(entry => {

  let list = [...entry.keywords];
    return (
      list.reduce(( finalArray, current ) => finalArray.concat(current),[])
  );
});

Within my React component, I iterate over the array using map again:

<p>
  keywords: {keywordList.map((word, index) => {
    return (
      <span key={word+index}>
        <a onClick={this.searchKeyword} href="#" id={word}>{word}</a>
        <span> | </span>
      </span>
    );

  })}
</p>

Unfortunately, my reduce function doesn't seem to be working, I'm getting an array of arrays. Any advice would be great.

Upvotes: 1

Views: 107

Answers (3)

GulshanZealous
GulshanZealous

Reputation: 638

const arr = [
  {
    "word":"Cat",
    "answer":"A type of feline",
    "keywords": ["pet", "mouse-catcher"]
  },
  {
    "word":"Dog",
    "answer":"A type of canine",
    "keywords": ["pet", "cat-catcher"]
  },
]

const keywords = [ ...arr.reduce((keywords,obj)=> [...keywords, ...obj.keywords ], [] )
                  .reduce((set,keyword)=> set.add(keyword), new Set() ) ]

The first reduce merges all keywords with repetition by concatenation and the second reduce converts the array into a Set removing all duplication. Finally, I wrap it with the resulting set with
[ ...Set ] to convert it into an array.

JS Bin

Upvotes: 0

Danil Speransky
Danil Speransky

Reputation: 30453

let data = [{
    "word": "Cat",
    "answer": "A type of feline",
    "keywords": ["pet", "mouse-catcher"]
  }, {
    "word": "Dog",
    "answer": "A type of canine",
    "keywords": ["pet", "cat-catcher"]
  }
]

let keywords = [...new Set(data.reduce((a, e) => a.concat(e.keywords), []))]

JSFiddle

Upvotes: 2

Andy
Andy

Reputation: 63524

Instead of map, a reduce with a filter:

var list = data.reduce((p, c) => {
  return p.concat(c.keywords.filter(el => !p.includes(el)));
}, []);

DEMO

Upvotes: 1

Related Questions