3

I have two arrays as below:

var product1 = [
    {
      "Brand": "One Plus"
    },
    {
      "Brand": "One Plus"
    }
  ];
var product2 = [
    {
      "Brand": "One Plus"
    },
    {
      "Brand": "Apple"
    }
  ];

I want to loop through the array and print the following:

  1. If product 1, output you have 2 One Plus
  2. If product 2, output you have 1 One Plus and 1 Apple

Below is the code that I tried.

var product1 = [
    {
      "Brand": "One Plus"
    },
    {
      "Brand": "One Plus"
    }
  ];
var product2 = [
    {
      "Brand": "One Plus"
    },
    {
      "Brand": "Apple"
    }
  ];

counter1 = {}
product1.forEach(function(obj) {
    var key = JSON.stringify(obj)
    counter1[key] = (counter1[key] || 0) + 1
});
console.log(counter1);
counter2 = {}
product2.forEach(function(obj) {
    var key = JSON.stringify(obj)
    counter2[key] = (counter2[key] || 0) + 1
});
console.log(counter2);

I’m able to get the JSON output, but how can I get it in the sentence format?

6
  • 3
    JSON is always a string. Commented Jun 2, 2020 at 17:55
  • 2
    Why are you doing JSON.stringify(obj) as key instead of just using obj.Brand Commented Jun 2, 2020 at 17:56
  • @user4642212 Is there a reason you rolled back that edit? It's quite clear that string isn't the keyword here. Commented Jun 2, 2020 at 17:57
  • @Brad I didn’t roll back the edit, I edited at the same time and looked back into the revision history to reapply your changes. It’s faster than to start from scratch. Commented Jun 2, 2020 at 17:59
  • 1
    I wouldn't use JSON at all. Just group and count: Group array of objects by value and get count of the groups, then reduce the keys and counts. Commented Jun 2, 2020 at 18:04

5 Answers 5

5

How about this?

var product1 = [{
    "Brand": "One Plus"
  },
  {
    "Brand": "One Plus"
  }
];
var product2 = [{
    "Brand": "One Plus"
  },
  {
    "Brand": "Apple"
  }
];

function countProducts(arr) {
  let counter = arr.reduce((acc, val) =>
    (acc[val.Brand] = (acc[val.Brand] || 0) + 1, acc), {});
  let strings = Object.keys(counter).map(k => `${counter[k]} ${k}`);
  return `You have ${strings.join(' and ')}`;
}

console.log(countProducts(product1));

console.log(countProducts(product2));

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

Comments

2

const product1 = [
  {Brand: "One Plus"},
  {Brand: "One Plus"},
];
const product2 = [
  {Brand: "One Plus"},
  {Brand: "Apple"},
];

function whatYouHaveIn(list) {
  return `You have ` + Object.entries(list.reduce((a, c) => {
    a[c.Brand] = a[c.Brand] || 0;
    a[c.Brand]++;
    return a;
  }, {})).map(([brand, count]) => `${count} ${brand}`).join(` and `);
}

console.log(whatYouHaveIn(product1));

console.log(whatYouHaveIn(product2));

Comments

2
const product1s = product1.reduce((acc, product) => {
acc[product.Brand] = (acc[product.Brand] || 0) + 1;
return acc;
}, {});

console.log(
`You have ${
Object.keys(product1s).map(product => `${product1s[product]} ${product}`).join(" and ")
}`
);

6 Comments

@gyohza indeed! Beat me to it! But check your return value in your reduction?
You mean this bit (acc[val.Brand] || 0) + 1? Yep, it's actually the exact same expression. :P
Actually it's a quite standard answer, so it's no wonder both are so alike.
@gyohza I meant returning acc after the comma, a neat JS shorthand I’ve forgotten about! Thanks!
Oh! Yeah. That is different between our codes, it seems. The comma operator was just syntactic sugar though - it's easier on the eyes not to have to create a new block for the function body.
|
0

You first have to count the occurances, than its just a matter of string concat or templates

function strinify(a) {
  let occurances = {};
  
  a.forEach(function(e,i){
   if( e.Brand in occurances ) {
    occurances[e.Brand] ++;
   } else {
    occurances[e.Brand] = 1;
   }
  });
   
  let str = [];
  
  for( brand in occurances ){
    count = occurances[brand];
    str.push(count + " " + brand);
  }; 
  
  return "you have " + str.join(" and ");
}
  
console.log(strinify([
    {
      "Brand": "One Plus"
    },
    {
      "Brand": "One Plus"
    },
    {
      "Brand": "Apple"
    }
]));

Comments

0

const order1 = [
  {
    "Brand": "One Plus",
    "test" : "test"
  },
  {
    "Brand": "One Plus"
  },
  {
  	"Bar": "Foo"
  }
];
const order2 = [
  {
    "Brand": "One Plus"
  },
  {
    "Brand": "Apple"
  }
];

const orderToString = (order) => {
  if(order == null) return;
  
  const productsWithBrand = order.filter(product => Object.keys(product).includes('Brand'));
  const productBrandCounter = (counter, product) => (counter[product.Brand] = (counter[product.Brand] || 0) + 1, counter);
  const countPerProduct = productsWithBrand.reduce(productBrandCounter, {});
  const stringPerProduct = Object.keys(countPerProduct).map(brand => `${countPerProduct[brand]} ${brand}`);

  return `You have ${stringPerProduct.join(' and ')}`;
}

console.log(orderToString(order1));

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.