12

I am fetching data by an API. It is a movie, tv show, person database. When I search a word in the search box, it returns the related movie, tv show and person names in objects nested in an array. for example when I search "fight":

    [
    0:{original_name: "쌈 마이웨이", id: 70813, media_type: "tv", name: "Fight My Way", vote_count: 5,…}

    1:{vote_average: 8.2, vote_count: 8057, id: 550, video: false, media_type: "movie", title: "Fight Club",…}

    2:{vote_average: 6.1, vote_count: 215, id: 345922, video: false, media_type: "movie",…}

    3:{original_name: "Fight", id: 46554, media_type: "tv", name: "Fight", vote_count: 0, vote_average: 0,…}

    4:{original_name: "The Good Fight", id: 69158, media_type: "tv", name: "The Good Fight", vote_count: 22,…}

    5:{vote_average: 0, vote_count: 0, id: 158301, video: false, media_type: "movie", title: "Fight",…}
   ]

there are more results but I cut them. As you can see there are media_type properties in each object. there are 3 media types as you can understand (movie, tv, person). I want to count each type.

actually; I want the same thing in the link I guess: React: Syntax for calling setState in Switch Return

but it doesn't work for me. I tried to change simply the state of movieCount to 3 like this:

countType() {
        this.props.movies.map(movie => {
            return() => {
            if(movie.media_type === 'movie') {
                this.setState({ movieCount: 3});
                console.log(this.state);
            }
            }
        });
    }

but it doesn't work too.and I researched on the internet this stuff in javascript documentation and forums. not about just react. but I couldn't do anything. I know it's simple.

so how can I count objects in an array according to their property types?

4 Answers 4

14

Assuming that the data you fetched from API is stored in data variable, you can try the following code to find the count of movie media type in your data array:

const movies = data.filter(item => item.media_type === 'movie'));
const moviesCount = movies.length;

You can also dynamically calculate count of every media_type in your data array:

const mediaTypes = data
    .map(dataItem => dataItem.media_type) // get all media types
    .filter((mediaType, index, array) => array.indexOf(mediaType) === index); // filter out duplicates
  
const counts = mediaTypes
  .map(mediaType => ({
    type: mediaType,
    count: data.filter(item => item.media_type === mediaType).length
  }));

Then counts will be something like this:

[
  {
    "type": "tv",
    "count": 3
  },
  {
    "type": "movie",
    "count": 3
  }
]
Sign up to request clarification or add additional context in comments.

3 Comments

in this code, is data paramater my movies array? so dont i need map function?
Yes, data is the array which you posted in the question. I've edited the answer.
thanks man. i just solve it like: const countTypes = this.props.movies.filter(movie => movie.media_type === type); const movieCounted = countTypes.length;
3

ok i found the solition. thank you to poohitan for answer. i solved it through his answer.

countType(type) {
        const countTypes = this.props.movies.filter(movie => movie.media_type === type);
        return countTypes.length;
    }

and while i am rendering my tv results, i just call the method above with type. for example:

return ( 
    <div> 
      movie count: {this.countType('movie')} 
      tv show count: {this.countType('tv')} 
    </div> 
    );

2 Comments

It breaks once props get updated. "this.props.movies.filter is not a function". Any idea how to get around it ?
How did you exactly call the function? It seems that you miss binding or you didn't pass props correctly. (Maybe wrote props name wrong)
0
var data = [
    { original_name: "쌈 마이웨이", id: 70813, media_type: "tv", name: "Fight My Way", vote_count: 5 },

    { vote_average: 8.2, vote_count: 8057, id: 550, video: false, media_type: "movie", title: "Fight Club" },

    { vote_average: 6.1, vote_count: 215, id: 345922, video: false, media_type: "movie" },

    { original_name: "Fight", id: 46554, media_type: "tv", name: "Fight", vote_count: 0, vote_average: 0 },

    { original_name: "The Good Fight", id: 69158, media_type: "tv", name: "The Good Fight", vote_count: 22 },

    { vote_average: 0, vote_count: 0, id: 158301, video: false, media_type: "movie", title: "Fight" },
]

this.types = {};

data.forEach((d) => {
    if (!this.types[d["media_type"]]) {
        this.types[d["media_type"]] = 1;
    } else {
        this.types[d["media_type"]] += 1;
    }
})

console.log(this.types);
// you will get answer { tv: 3, movie: 3 }

Comments

0

Here's one possible way:

render()  {
    let countTypes = ' '
         return ({
             list.length > 0
                 ?
                  <span> {countTypes = (list.filter(moviesFilter => 
                  moviesFilter.type.id === this.props.typeId)).length} 
                  </span>
                :
                  <DisplayMessage message="0" />
        })
}  

Comments

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.