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 acplish is when the order es 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 es back as name = 0 and the value being the individual nested object inside the main object.
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 acplish is when the order es 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 es back as name = 0 and the value being the individual nested object inside the main object.
JSON.parse(string)
, which can then be treated like any other Object.
– RobG
Commented
Dec 26, 2014 at 0:40
[{"product 2":15}]
?
– whitfin
Commented
Dec 26, 2014 at 0:52
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
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>
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