1

I want to count the number of entries based on the color inputted by user , like if user input red , the program should return 11. This is what I tried. The variable cnt is not defined after the loop.

let description=[
                {color:'red',qty:6,remarks:'asdf'},
                {color:'green',qty:5,remarks:'asdf'},
                {color:'red',qty:5,remarks:'asdf'},                             
                {color:'yellow',qty:5,remarks:'asdf'},                         
                {color:'blue',qty:5,remarks:'asdf'},                           
                {color:'white',qty:5,remarks:'asdf'}
                ];
{description.map((t,index) =>{
         let cnt=0;
         if(t.color=='red'){
            cnt=cnt+parseInt(t.qty);    
         }
         console.log(cnt);
      }   
      )}
 console.log(cnt);     

1
  • let is scope specific. It's going to be re-created on each iteration and won't be defined once you leave it. Instead move it outside of your function and it will work. Commented Apr 24, 2018 at 3:01

6 Answers 6

3

The problem on your code is you initialise let cnt=0; inside the function and on every reiteration, which means you are not actually adding the values since you are resetting the cnt to 0 on every loop.

You can use reduce and test if color is colorToSearch, if the same add the accumulator and current qty value.

let description=[
     {color:'red',qty:6,remarks:'asdf'},
     {color:'green',qty:5,remarks:'asdf'},
     {color:'red',qty:5,remarks:'asdf'},                             
     {color:'yellow',qty:5,remarks:'asdf'},                         
     {color:'blue',qty:5,remarks:'asdf'},                           
     {color:'white',qty:5,remarks:'asdf'}
];

let colorToSearch = 'red';

let totalQty = description.reduce((c, v) => v.color === colorToSearch ? c + v.qty : c, 0)

console.log(totalQty);

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

1 Comment

ah you beat me by few seconds :)
0

You can filter the array first and apply reduce like below

let description=[
                {color:'red',qty:6,remarks:'asdf'},
                {color:'green',qty:5,remarks:'asdf'},
                {color:'red',qty:5,remarks:'asdf'},                             
                {color:'yellow',qty:5,remarks:'asdf'},                         
                {color:'blue',qty:5,remarks:'asdf'},                           
                {color:'white',qty:5,remarks:'asdf'}
                ];
                
 let s=description.filter(description => description.color === 'red').reduce(function(sum, currentValue) {
                 return sum + (parseInt(currentValue.qty) || 0);},0)
 console.log(s);               

1 Comment

hmm . I saw parse int on OP's post and its easy to check falsey value as well.
0

You can use Array.prototype.reduce() as follows:

const description=[
  {color:'red',qty:6,remarks:'asdf'},
  {color:'green',qty:5,remarks:'asdf'},
  {color:'red',qty:5,remarks:'asdf'},                             
  {color:'yellow',qty:5,remarks:'asdf'},                         
  {color:'blue',qty:5,remarks:'asdf'},                           
  {color:'white',qty:5,remarks:'asdf'}
];
const color = 'red';
const qty = description.reduce((a, v) => a + (v.color == color ? v.qty : 0), 0);

console.log(qty);

Comments

0

Your variable ctn is re-defined on each iteration and only exist within your .map function. That's why you get an error "The variable cnt is not defined" after the loop finishes.

All you need to do is move ctn outside of your .map and it will work:

let description=[
                {color:'red',qty:6,remarks:'asdf'},
                {color:'green',qty:5,remarks:'asdf'},
                {color:'red',qty:5,remarks:'asdf'},                             
                {color:'yellow',qty:5,remarks:'asdf'},                         
                {color:'blue',qty:5,remarks:'asdf'},                           
                {color:'white',qty:5,remarks:'asdf'}
                ];
                
let cnt=0;    

description.map((t,index) => {
         if(t.color=='red'){
            cnt=cnt+parseInt(t.qty); //Note: parseInt() isn't needed if qty is always a number
         }
      });
      
 console.log(cnt);

Comments

0

You can use either array filter or array reduce method. Below is an example with array reduce.

In you program let cnt=0; is inside the map function. So the value of cnt will not be available in the second console.log statement

let description = [{
    color: 'red',
    qty: 6,
    remarks: 'asdf'
  },
  {
    color: 'green',
    qty: 5,
    remarks: 'asdf'
  },
  {
    color: 'red',
    qty: 5,
    remarks: 'asdf'
  },
  {
    color: 'yellow',
    qty: 5,
    remarks: 'asdf'
  },
  {
    color: 'blue',
    qty: 5,
    remarks: 'asdf'
  },
  {
    color: 'white',
    qty: 5,
    remarks: 'asdf'
  }
];



function getCount(matchedColor) {
  return description.reduce(function(acc, curr) {
    //Now checking if the color is matching with supplied paramenter
    if (curr.color === matchedColor) {
      acc += curr.qty // add with previous value
    };
    return acc
  }, 0) // zero is initial value, that is initially the sum is zero
}
console.log(getCount('red'));

Comments

0

I personally think using filter then reduce to get the sum is a more readable solution.

let description = [
  {color:'red',qty:6,remarks:'asdf'},
  {color:'green',qty:5,remarks:'asdf'},
  {color:'red',qty:5,remarks:'asdf'},                             
  {color:'yellow',qty:5,remarks:'asdf'},                         
  {color:'blue',qty:5,remarks:'asdf'},                           
  {color:'white',qty:5,remarks:'asdf'}
];
let result = description.filter(item => item.color === 'red').reduce((prev, {qty}) => prev + qty, 0);
console.log(result);

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.