1

i have the following JavaScript

{
  "business": [
{
  "order_contents": [
    {
      "id": 83,
      "name": "product 1",
      "price": "1.99",
      "quantity": 1,
      "total": "1.99",
      "ingredients": [],
      "extras": []
    },
    {
      "id": 83,
      "name": "product 1",
      "price": "1.99",
      "quantity": 1,
      "total": "1.99",
      "ingredients": [],
      "extras": []
    },
    {
      "id": 83,
      "name": "product 1",
      "price": "1.99",
      "quantity": 1,
      "total": "1.99",
      "ingredients": [],
      "extras": []
    },
    {
      "id": 85,
      "name": "product 3",
      "price": "1.99",
      "quantity": 1,
      "total": "1.99",
      "ingredients": [],
      "extras": []
    },
    {
      "id": 83,
      "name": "product 1",
      "price": "1.99",
      "quantity": 1,
      "total": "1.99",
      "ingredients": [],
      "extras": []
    },
    {
      "id": 84,
      "name": "product 2",
      "price": "1.99",
      "quantity": 1,
      "total": "1.99",
      "ingredients": [],
      "extras": []
    },
    {
      "id": 83,
      "name": "product 1",
      "price": "1.99",
      "quantity": 1,
      "total": "1.99",
      "ingredients": [],
      "extras": []
    },
    {
      "id": 83,
      "name": "product 1",
      "price": "1.99",
      "quantity": 1,
      "total": "1.99",
      "ingredients": [],
      "extras": []
    },
    {
      "id": 83,
      "name": "product 1",
      "price": "1.99",
      "quantity": 1,
      "total": "1.99",
      "ingredients": [],
      "extras": []
    },
    {
      "id": 83,
      "name": "product 1",
      "price": "1.99",
      "quantity": 1,
      "total": "1.99",
      "ingredients": [],
      "extras": []
    },
    {
      "id": 83,
      "name": "product 1",
      "price": "1.99",
      "quantity": 1,
      "total": "1.99",
      "ingredients": [],
      "extras": []
    },
    {
      "id": 83,
      "name": "product 1",
      "price": "1.99",
      "quantity": 1,
      "total": "1.99",
      "ingredients": [],
      "extras": []
    },
    {
      "id": 84,
      "name": "product 2",
      "price": "1.99",
      "quantity": 1,
      "total": "1.99",
      "ingredients": [],
      "extras": []
    }
   ]
  }
 ]
}

What i am trying to accomplish is when the order comes through a function scans the JSON and creates an array with each unique product name and adds 1 to the quantity each time.

i have tried using a for loop but it loops it the amount of times but doesn't find the name and value in the nested object of each one, it comes back as name = 0 and the value being the individual nested object inside the main object.

5
  • 1
    What does your function look like which does the looping and adding to the quantity? Commented Dec 26, 2014 at 0:29
  • JSON is a string. It can be converted to a javascript Object using JSON.parse(string), which can then be treated like any other Object. Commented Dec 26, 2014 at 0:40
  • What does the output array look like that contains names and counts? Commented Dec 26, 2014 at 0:43
  • I'm assuming you want output of something like [{"product 2":15}]? Commented Dec 26, 2014 at 0:52
  • Okay.. so are you're trying to reduce the array items based on their name into separate arrays? Commented Dec 26, 2014 at 1:41

3 Answers 3

4

A function like the beneath would work. Basically you pass the array as parameter and return an object that 1) gets a new property if the property does not exist yet (eg. the product id), and 2) adds to the count of items when the property does exist. The function below generates an output like: {'product 1': 10, 'product 2': 1, 'product 3': 2}

function getItems(input) {
  var arr = input, obj = {};
  for (var i = 0; i < arr.length; i++) {
    if (!obj[arr[i].name]) {
      obj[arr[i].name] = 1;
    } else if (obj[arr[i].name]) {
      obj[arr[i].name] += 1;
    }
  }
  return obj;
}
// example use
console.log(getItems(order_contents)); // outputs entire object
console.log(getItems(order_contents)['product 1']); // outputs 10
Sign up to request clarification or add additional context in comments.

1 Comment

!obj[arr[i].name] should be !(arr[i].name in ob) since the property may exist but return a falsey value. It doesn't matter here though. ;-) Also more generic and less code to use: var p = arr[i].name; if (!(p in ob)){obj[p] = 0;} ++obj[p];.×Comments can't contain that content.×Comments can't contain that content.×Comments can't contain that content. Plus 1 anyway.
0

Seeing that you need unique names for each product... you can push the objects into a grouped array of objects then reduce the objects into single unique objects.

var data={"business":[{"order_contents":[{"id":83,"name":"product 1","price":"1.99","quantity":1,"total":"1.99","ingredients":[],"extras":[]},{"id":83,"name":"product 1","price":"1.99","quantity":1,"total":"1.99","ingredients":[],"extras":[]},{"id":83,"name":"product 1","price":"1.99","quantity":1,"total":"1.99","ingredients":[],"extras":[]},{"id":85,"name":"product 3","price":"1.99","quantity":1,"total":"1.99","ingredients":[],"extras":[]},{"id":83,"name":"product 1","price":"1.99","quantity":1,"total":"1.99","ingredients":[],"extras":[]},{"id":84,"name":"product 2","price":"1.99","quantity":1,"total":"1.99","ingredients":[],"extras":[]},{"id":83,"name":"product 1","price":"1.99","quantity":1,"total":"1.99","ingredients":[],"extras":[]},{"id":83,"name":"product 1","price":"1.99","quantity":1,"total":"1.99","ingredients":[],"extras":[]},{"id":83,"name":"product 1","price":"1.99","quantity":1,"total":"1.99","ingredients":[],"extras":[]},{"id":83,"name":"product 1","price":"1.99","quantity":1,"total":"1.99","ingredients":[],"extras":[]},{"id":83,"name":"product 1","price":"1.99","quantity":1,"total":"1.99","ingredients":[],"extras":[]},{"id":83,"name":"product 1","price":"1.99","quantity":1,"total":"1.99","ingredients":[],"extras":[]},{"id":84,"name":"product 2","price":"1.99","quantity":1,"total":"1.99","ingredients":[],"extras":[]}]}]};

function buildData() {
	var items = data.business[0].order_contents, elems = [], groups = [];
	for( var i = 0; i < items.length; i++ ) {
		Array.prototype.push.call( elems, items[i] );
	}
	groups.push( groupBy( elems, function( item ) {
		return item;
	} ) );
	groupBy( groups, function( array ) {
		for( var i = 0; i < array.length; i++ ) {
			var obj = array[i].slice();
			Object.keys( obj ).map( function( p ) {
				var length = obj.length;
				if( obj[p].hasOwnProperty( "quantity" ) ) {
					obj[p].quantity = length;
				}
				groups[i] = obj[p];
			} );
		}
	} );
	function groupBy( array, f ) {
		var groups = {};
		array.forEach( function( o ) {
			var group = JSON.stringify( f( o ) );
			groups[group] = groups[group] || [];
			groups[group].push( o );
		} );
		return Object.keys( groups ).map( function( group ) {
			return groups[group];
		} );
	}

	return groups;
}

(function() {
	var old = console.log;
	var logger = document.getElementById( 'log' );
	console.log = function( message ) {
		if( typeof message == 'object' ) {
			logger.innerHTML += (JSON && JSON.stringify ? JSON.stringify( message, undefined, 2 ) : message) + '<br />';
		} else {
			logger.innerHTML += message + '<br />';
		}
	}
})();

console.log( buildData() );
<pre id="log">
</pre>

1 Comment

I think you missed "…each unique product name".
0

Not a big fan of reinventing the wheel, so here is how you could use object-scan to answer your question

// const objectScan = require('object-scan');

const counts = (haystack) => objectScan(['business[*].order_contents[*].name'], {
  filterFn: ({ value, context }) => {
    context[value] = (context[value] || 0) + 1;
  }
})(haystack, {});

const data = { business: [{ order_contents: [{ id: 83, name: 'product 1', price: '1.99', quantity: 1, total: '1.99', ingredients: [], extras: [] }, { id: 83, name: 'product 1', price: '1.99', quantity: 1, total: '1.99', ingredients: [], extras: [] }, { id: 83, name: 'product 1', price: '1.99', quantity: 1, total: '1.99', ingredients: [], extras: [] }, { id: 85, name: 'product 3', price: '1.99', quantity: 1, total: '1.99', ingredients: [], extras: [] }, { id: 83, name: 'product 1', price: '1.99', quantity: 1, total: '1.99', ingredients: [], extras: [] }, { id: 84, name: 'product 2', price: '1.99', quantity: 1, total: '1.99', ingredients: [], extras: [] }, { id: 83, name: 'product 1', price: '1.99', quantity: 1, total: '1.99', ingredients: [], extras: [] }, { id: 83, name: 'product 1', price: '1.99', quantity: 1, total: '1.99', ingredients: [], extras: [] }, { id: 83, name: 'product 1', price: '1.99', quantity: 1, total: '1.99', ingredients: [], extras: [] }, { id: 83, name: 'product 1', price: '1.99', quantity: 1, total: '1.99', ingredients: [], extras: [] }, { id: 83, name: 'product 1', price: '1.99', quantity: 1, total: '1.99', ingredients: [], extras: [] }, { id: 83, name: 'product 1', price: '1.99', quantity: 1, total: '1.99', ingredients: [], extras: [] }, { id: 84, name: 'product 2', price: '1.99', quantity: 1, total: '1.99', ingredients: [], extras: [] }] }]};

console.log(counts(data));
// => { 'product 2': 2, 'product 1': 10, 'product 3': 1 }
.as-console-wrapper {max-height: 100% !important; top: 0}
<script src="https://bundle.run/[email protected]"></script>

Disclaimer: I'm the author of object-scan

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.