Function in Vue for calculating the number of duplicate elements in an array

I have successfully created a new array containing only unique values, but I am facing issues with my count function. The desired result is to display the number of items in the array for each color.

The expected outcome would be:

4 red
10 blue
1 green

Currently, the result shows a count of 0 for each color. I suspect this may be due to me adding the count property while mapping the array to a new variable.

I used the if (loopComplete == false) condition because I was encountering undefined errors and wanted to ensure that the second for loop runs after the first one completes.

var vm = new Vue({
  el: '#app',
  data: {
    myArray: [
      { color: 'red',
        number: '1'
      },
      {
        color: 'red',
        number: '2'
      },
      // other array elements...
    ],
  },
  computed: {
    filteredArray() {
      return this.count(this.myArray);
    }
  },
  methods: {
    count(array) {
      let newArray = array.map(function(item) {
        return {
          'color': item.color,
          'count': 0,
        };
      });
      let arrayUnique = [];
      let arrayAdded = [];
      let loopComplete = false;

      if (loopComplete == false) {
        for (let i = 0; i < newArray.length; i++) {
          if (!arrayAdded.includes(newArray[i].color)) {
            arrayAdded.push(newArray[i].color);
            arrayUnique.push(newArray[i]);
          }
        }
        loopComplete = true;
        return arrayUnique;
      } else {
        for (let i = 0; i < newArray.length; i++) {
          if (arrayUnique.includes(newArray[i].color)) {
            arrayUnique[i].count++;
          }
          return arrayUnique;
        }
      }
    }
  }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
  <div v-for="result in filteredArray">
    {{ result.count }} {{ result.color }}
  </div>
</div>

Answer №1

To solve this problem, consider utilizing a for loop.

var vm = new Vue({
  el: '#app',
  data: {
    myArray: [
      { color: 'red',
        number: '1'
      },
      {
        color: 'red',
        number: '2'
      },
      {
        color: 'red',
        number: '3'
      },
      {
        color: 'red',
        number: '4'
      },
      {
        color: 'blue',
        number: '5'
      },
      {
        color: 'blue',
        number: '6'
      },
      {
        color: 'blue',
        number: '7'
      },
      {
        color: 'blue',
        number: '8'
      },
      {
        color: 'blue',
        number: '9'
      },
      {
        color: 'blue',
        number: '10'
      },
      {
        color: 'blue',
        number: '11'
      },
      {
        color: 'blue',
        number: '12'
      },
      {
        color: 'blue',
        number: '13'
      },
      {
        color: 'blue',
        number: '14'
      },
      {
        color: 'green',
        number: '15'
      },
    ],
  },
  computed: {
    filteredArray() {
      var result = {}
      for (let index in this.myArray) {
        let key = this.myArray[index].color
        result[key] = {
           color: key,
           count: result[key] && result[key].count ? result[key].count + 1 : 1
        }
      }
      return Object.values(result)
    }
  }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
  <div v-for="item in filteredArray">
    {{ item.count }} {{ item.color }}
  </div>
  <pre>{{filteredArray}}</pre>
</div>

Answer №2

To avoid using conditional logic and the .includes() method, you can convert the array into a map by utilizing .reduce(). The resulting structure will resemble this:

{
  red: 4,
  blue: 10,
  green: 1
}

Afterwards, you can apply .map() to achieve your desired format.

var vm = new Vue({
  el: '#app',
  data: {
    myArray: [ { color: 'red', number: '1' }, { color: 'red', number: '2' }, { color: 'red', number: '3' }, { color: 'red', number: '4' }, { color: 'blue', number: '5' }, { color: 'blue', number: '6' }, { color: 'blue', number: '7' }, { color: 'blue', number: '8' }, { color: 'blue', number: '9' }, { color: 'blue', number: '10' }, { color: 'blue', number: '11' }, { color: 'blue', number: '12' }, { color: 'blue', number: '13' }, { color: 'blue', number: '14' }, { color: 'green', number: '15' }, ],
  },
  computed: {
    filteredArray() {
      return this.count(this.myArray);
    }
  },
  methods: {
    count(array) {
      //add 1 if the color exists, initialize as 1 if it does not
      let counts = array.reduce((out, {color}) => ({ ...out, [color]: out[color]+1 || 1}), {});
      return Object.keys(counts).map(key => ({color: key, count: counts[key]}));
    }
  }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
  <div v-for="result in filteredArray">
    {{ result.count }} {{ result.color }}
  </div>
</div>

Answer №3

To start, retrieve all the different colors by utilizing the arr.map() method:

const uniqueColors = myArray.map(item => item.color);

Then proceed to tally up each color within this array:

let colorCounts = {};
for (let j = 0; j < uniqueColors.length; j++) {
    colorCounts[uniqueColors[j]] = (colorCounts[uniqueColors[j]] + 1) || 1;
}

Your updated filteredArray will now look like this:

filteredArray = Object.keys(colorCounts).reduce((accumulator, currentColor) => {
    accumulator.push({color: currentColor, count: colorCounts[currentColor]});
    return [...accumulator]
}, [])

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

What could be causing my browser to display "uncaught referenceerror" in this situation?

Just running some browser tests to troubleshoot - everything's smooth sailing until this line is reached: responseJson = JSON.parse(localReq.responseText); So, when I evaluate JSON.parse(localReq.responseText), the correct value comes through. But a ...

Expand the size of the card box with CSS to create a larger and more prominent display

I recently came across a snippet of Javascript and CSS code. Here is the Javascript: $('.item-card').css("width", $('.item-card').width() + "px"); $('.item-card').css("font-size", $('.item-card').width() * .13 + "p ...

When trying to reference a vanilla JavaScript file in TypeScript, encountering the issue of the file not being recognized

I have been attempting to import a file into TypeScript that resembles a typical js file intended for use in a script tag. Despite my efforts, I have not found success with various methods. // global.d.ts declare module 'myfile.js' Within the re ...

Mistake in closing the component by the parent is causing an issue with Vuetify's v-dialog functionality

Recently, I encountered a situation where a component contained a straightforward v-dialog to display a message to the user and a v-btn to close it. The sequence of events went as follows: The user clicked on the button that triggered the v-dialog's ...

Having trouble with jQuery's load() function not functioning as expected?

I am struggling with my jQuery ajax code. I have a div that should load content from a file when clicked, but nothing is happening. Can someone please review my script and help me identify the mistake? Here is my JavaScript code: $(document).ready(functi ...

Organizing JSON data with keys in Android Studio using Java

As someone who is new to java and android development, I am currently focusing on learning json parsing. Recently, I received a json response that looks like this: {"code":"0","data": [ {"chrDesigName":"Developer","chrempName":"Test Employee1"}, {"c ...

How can I use HTML to display a new image next to the base image when I hover over it, showing both images side by side?

Looking for assistance with creating a comic webpage containing 2 cartoons. I want the dialog or mind-thought of each cartoon to appear on the page when a user hovers over them. Anyone able to offer some help with this? ...

Using duplicate named slots in Vue: A simple guide

As I work on creating a wrapped component for the v-stepper in Vuetify, my goal is to allow the user to define a slot when using the component. This slot name will then be used to construct the steps within the stepper. I encountered an issue with display ...

Encountering a TypeScript error while calling a Vue lifecycle hook method

Struggling to call a method in a Vue root component from a lifecycle method in typescript? See below for a simple example that showcases this issue: import Vue from "vue"; class Game { a: number; b: number; constructor() { this.a = 3; ...

"Exclusive Mui sx styles will be applied only when a specific breakpoint

As I update my old mui styling to utilize the sx attribute, I've noticed the ability to specify styles for different breakpoints using sx = {{ someCssProp: { xs: ..., md: ... and so on. Prior to this, I had been using theme.breakpoints.only for some ...

Deselect the checkboxes within an array

I've been grappling with a script to reset all checkboxes in a Google Sheet to unchecked as part of my daily cleanup routine. I've managed to identify and uncheck checkboxes in one sheet but am struggling to efficiently extend this to all sheets. ...

Sending a page identifier through a menu

Being new to vue/nuxt, I encountered an issue when setting up the frontend for a headless CMS. I have defined two routes as follows: Pages -StandardPage ->_standardPage.vue -InfoPage ->_InfoPage.vue Both my _standardPage.vue and _infoPage.v ...

Bootstrap 4 tabs function perfectly in pairs, but encounter issues when there are three of them

Having trouble with bootstrap4 tabs not working properly? They function well with 2 tabs using the code below: <div class="row"> <div class="col-12"> <ul class="nav nav-tabs" id="registration-picker-acc-select" role="tablist"> ...

Transform a string (variable) into an object using JSON.parse, encountering an unexpected token error

I am struggling with parsing a string variable back to an object. Despite searching through various posts on this issue, I have not found a solution that works for me. if(subMatch.match(/\{.*\}/)){ /// new Object of some sort var o ...

Terminate the connection with nginx abruptly

Is there a way for nginx to immediately close the TCP connection once the request has been completed? ...

I encountered a SyntaxError that reads "Unexpected token instanceof" while using the Chrome Javascript console

I find it quite surprising that the code below, when entered into the Chrome JavaScript console: {} instanceof Object leads to the error message displayed below: Uncaught SyntaxError: Unexpected token instanceof Could someone kindly explain why this ...

Adjusting the font size based on the text length and the size of the parent div

React/Javascript I am working on a challenge involving a div element that contains a paragraph. This paragraph may vary in length, so I need to find a way to dynamically adjust the font size based on its length. If the paragraph is longer, I want to scale ...

What is the approach of Angular 2 in managing attributes formatted in camelCase?

Recently, I've been dedicating my time to a personal project centered around web components. In this endeavor, I have been exploring the development of my own data binding library. Progress has been made in creating key functionalities akin to those f ...

Present a pop-up notification box with a countdown of 30 seconds prior to the expiration of a session timeout in JSF

Our task is to create a timeout window that appears 30 seconds before the session expires. If the user remains inactive, they will be automatically redirected to the home page. We already have the maximum allowed duration of inactivity defined. I would l ...

"Step-by-step guide on deactivating SmartyStreets/LiveAddress with an onclick function

I've recently taken over a SquirrelCart shopping cart application that utilizes SmartyStreets/LiveAddress code, and I'm struggling to figure out how to disable the verification process when copying billing address fields to shipping address field ...