简体   繁体   中英

Find unique values from an array in React/js

I'm a beginner in JavaScript and an even bigger beginner in ReactJS. Most of the following I've taken from tutorials and am trying to adapt it. So the codes displays all the values from the "tag" (people, places, places, etc.). It displays it as inline li elements as it's going to be a menu. The problem is that it displays all the tag for all the elements. I just want it to catch the unique 'tag' values for the menu (eg. people, places, things,...). I've tried _.uniq but it did not display the array. Thank you.

import React from "react";
import GalleryHeader from './GalleryHeader';
import ImageEntry from './ImageEntry';
import _ from 'lodash';

export default class GalleryImages extends React.Component {

    renderItems() {
        return _.map(this.props.images, (image, index) => <ImageEntry key={index} {...image} />);
    }

  renderMenu() {
    return _.map(this.props.images, (image, index) => <GalleryHeader key={index} {...image} />);
  }


  render() {

    return (
      <div>
      <ul class="list-inline">
        {this.renderMenu()}
      </ul>
        {this.renderItems()}          
      </div>
    );
  }
}

GalleryHeader

import React from "react";


export default class GalleryHeader extends React.Component {

  render() {

    return (
            <li>{this.props.tag}</li>
    );
  }
}

Images are stored in:

Gallery

import React from "react";

import GalleryImages from './Gallery/GalleryImages';


var images = [{
  "id": 1,
  "tag": "people",
  "src": "img/img1.jpg",
  "bsrc": "img/img1b.jpg",
  "alt": "Some description"
}, {
  "id": 2,
  "tag": "places",
  "src": "img/img2.jpg",
  "bsrc": "img/img2b.jpg",
  "alt": "Some description"
}, {
  "id": 3,
  "tag": "places",
  "src": "img/img3.jpg",
  "bsrc": "img/img3b.jpg",
  "alt": "Some place description"
}, {
  "id": 4,
  "tag": "things",
  "src": "img/img4.jpg",
  "bsrc": "img/img4b.jpg",
  "alt": "Internet of things"
}, {
  "id": 5,
  "tag": "people",
  "src": "img/img5.jpg",
  "bsrc": "img/img5b.jpg",
  "alt": "A personal person"
}, {
  "id": 6,
  "tag": "places",
  "src": "img/img6.jpg",
  "bsrc": "img/img6b.jpg",
  "alt": "Interesting place"
}, {
  "id": 7,
  "tag": "people",
  "src": "img/img7.jpg",
  "bsrc": "img/img7b.jpg",
  "alt": "Tarabaora"
}, {
  "id": 8,
  "tag": "places",
  "src": "img/img6.jpg",
  "bsrc": "img/img6b.jpg",
  "alt": "Interesting place"
}, {
  "id": 9,
  "tag": "places",
  "src": "img/img6.jpg",
  "bsrc": "img/img6b.jpg",
  "alt": "Interesting place"
}];

export default class Gallery extends React.Component {
  constructor(props) {
    super(props);

    this.state = {
      images,
      people: _.filter(images, {tag: "things"}),    // or in ES6 just people
      sources: _.filter(images, {tag: "src"}),
      places: _.filter(images, {tag: "places"}),
      cats: _.uniq(images)
    };
  }

  render() {
    // This is how you can filter them
    var ima = _.filter(images, {tag: "things"});
    console.log(ima);


    return (
      <div className="koko">
        <h1>This isGalleryfemCount</h1>
        <GalleryImages images={this.state.images} />
      </div>
    );
  }
}

As I understand, you want to filter out original image collection by given tag. Correct?
If so, create filter function, which accepts tag and collection to filter. You can reuse this function then.

var images = [{
  "id": 1,
  "tag": "people",
  "src": "img/img1.jpg",
  "bsrc": "img/img1b.jpg",
  "alt": "Some description"
}, {
  "id": 2,
  "tag": "places",
  "src": "img/img2.jpg",
  "bsrc": "img/img2b.jpg",
  "alt": "Some description"
}, {
  "id": 3,
  "tag": "places",
  "src": "img/img3.jpg",
  "bsrc": "img/img3b.jpg",
  "alt": "Some place description"
}, {
  "id": 4,
  "tag": "things",
  "src": "img/img4.jpg",
  "bsrc": "img/img4b.jpg",
  "alt": "Internet of things"
}, {
  "id": 5,
  "tag": "people",
  "src": "img/img5.jpg",
  "bsrc": "img/img5b.jpg",
  "alt": "A personal person"
}, {
  "id": 6,
  "tag": "places",
  "src": "img/img6.jpg",
  "bsrc": "img/img6b.jpg",
  "alt": "Interesting place"
}, {
  "id": 7,
  "tag": "people",
  "src": "img/img7.jpg",
  "bsrc": "img/img7b.jpg",
  "alt": "Tarabaora"
}, {
  "id": 8,
  "tag": "places",
  "src": "img/img6.jpg",
  "bsrc": "img/img6b.jpg",
  "alt": "Interesting place"
}, {
  "id": 9,
  "tag": "places",
  "src": "img/img6.jpg",
  "bsrc": "img/img6b.jpg",
  "alt": "Interesting place"
}];

const filter = (tag, arr) => arr.filter(img => img.tag === tag);

// or in ES5
// var filter = function(tag, arr) {
//    return arr.filter(function(img) {
//        return img.tag === tag;
//    })
// };

const filtered = filter('people', images);

Edit
Added code to pick all unique tag names. Dependency free. Unline Set, this works in IE < 11.

const uniqueTags = [];
images.map(img => {
    if (uniqueTags.indexOf(img.tag) === -1) {
        uniqueTags.push(img.tag)
    }
});

It is similar The SQL SELECT DISTINCT Statement in javascript

      const uniqueTags = [];
                images.map(item => {                  
                    var findItem = uniqueTags.find(x => x.tag === item.tag);
                    if (!findItem)
                        uniqueTags.push(item);
                });

Since they are plain strings you can create a JavaScript Set for that.

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set

As stated in this documentation[1] we can use the uniqBy method to return the unique element in an object array. Please refer the below code.

import _ from 'lodash';
_.uniqBy([{ 'id': 100 }, { 'id': 200 }, { 'id': 300 },{ 'id': 100 }], 'id');

This will return an output like this [{ 'id': 100 }, { 'id': 200 }, { 'id': 300 }]

[1] https://lodash.com/docs/#uniqBy

Typescript sets source

For those who are using Typescripts I would recomend TypeScript Set

Array.from(new Set(yourArray.map((item: any) => item.id)))

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM