json object handling in JS - javascript

My given json object is as follows:
resultTable = [
{
id: "005470021180",
balance: "0.00",
accountName: "Money Master",
category: "Banking",
currency: "CAD",
entitlements: [
]
},
{
id: "005470021288",
balance: "0.00",
accountName: "Money Master",
category: "Banking",
currency: "CAD"
},
{
id: "005470044628",
balance: "-72,116.01",
accountName: "Money Master",
category: "Banking",
currency: "CAD"
},
{
id: "40592000495201",
accountName: "Business Loan",
category: "Borrowing",
cad_balance: "0.00"
},
{
id: "40592000495202",
accountName: "Business Loan",
category: "Borrowing",
cad_balance: "0.00"
},
{
id: "40592000495203",
accountName: "Business Loan",
category: "Investing",
cad_balance: "0.00"
},
{
id: "40592000495204",
accountName: "Business Loan",
category: "INVESTING",
cad_balance: "0.00"
},
{
usd_balance: "1,080.27",
id: "55300070",
accountName: "Scotia iTRADE",
category: "INVESTING",
cad_balance: "272,166.59"
}
];
I need an output in JS as :
resulttable = [
{
"Banking": {
id: "005470021180",
balance: "0.00",
accountName: "Money Master",
category: "Banking",
currency: "CAD",
entitlements: [
]
},
{
id: "005470021288",
balance: "0.00",
accountName: "Money Master",
category: "Banking",
currency: "CAD"
},
{
id: "005470044628",
balance: "-72,116.01",
accountName: "Money Master",
category: "Banking",
currency: "CAD"
}
},
{
"Borrowing": {
id: "40592000495201",
accountName: "Business Loan",
category: "Borrowing",
cad_balance: "0.00"
},
{
id: "40592000495202",
accountName: "Business Loan",
category: "Borrowing",
cad_balance: "0.00"
}
},
{
""INVESTING":{
{
id : "40592000495203",
accountName : "BusinessLoan",
category : "Investing",
cad_balance : "0.00"
},
{
id : "40592000495204",
accountName : "BusinessLoan",
category : "INVESTING",
cad_balance : "0.00"
},
{
usd_balance : "1,080.27",
id : "55300070",
accountName : "ScotiaiTRADE",
category : "INVESTING",
cad_balance : "272,166.59"
}} ];

Try something like this:
function (input)
{
var output = new Object();
for(var i = 0, len=input.length; i<len; i++)
{
if(typeof output[input[i].category] === 'undefined')
{
output[input[i].category] = [];
}
output[input[i].category].push(input[i]);
}
return output;
}
input would be your starting object, and it returns the output in the structure you want.
Or at least what I think you'd wanted.

Related

Loop through JSON in dataLayer

I would like to get the summed value of all the arrays in the "products" object (price * quantity). The summed value should be returned in the return.
Do you have any ideas how to do that?
{
"event": "checkout",
"ecommerce": {
"checkout": {
"actionField": {
"step": 2,
"option": "Initiate checkout",
"action": "checkout"
},
"products": [
{
"id": "52",
"name": "Turystyczna kuchenka gazowa SMILE-KN-03/1K",
"price": 161.788618,
"brand": "",
"category": "kuchenki-elektryczne-i-gazowe",
"variant": "",
"quantity": "1"
},
{
"id": "36",
"name": "Kuchnia gazowa MPM-51-KGF-21",
"price": 641.463415,
"brand": "",
"category": "kuchnie-gazowe",
"variant": "",
"quantity": "1"
}
]
}
},
"gtm.uniqueEventId": 12
}
const g = {
event: 'checkout',
ecommerce: {
checkout: {
actionField: {
step: 2,
option: 'Initiate checkout',
action: 'checkout',
},
products: [
{
id: '52',
name: 'Turystyczna kuchenka gazowa SMILE-KN-03/1K',
price: 161.788618,
brand: '',
category: 'kuchenki-elektryczne-i-gazowe',
variant: '',
quantity: '1',
},
{
id: '36',
name: 'Kuchnia gazowa MPM-51-KGF-21',
price: 641.463415,
brand: '',
category: 'kuchnie-gazowe',
variant: '',
quantity: '1',
},
],
},
},
'gtm.uniqueEventId': 12,
};
const c = g.ecommerce.checkout.products.reduce((acc, curr) => {
acc += curr.price * curr.quantity;
return acc;
}, 0);
console.log(c)
guess you want something like this?

Update object value in array with values in other array using hashtables or hashmap

I have two arrays Array1 and Array2, i am updating rate of object in Array1 with rate of same object (With same ID) in Array 2. I have a functions that loops through both arrays to get desired result. After going through some of the answers on Stack overflow I feel Hash table is best suited to reduce the complexity. I was just curious to understand how same can be implemented using the has maps.
let Array1 = [{
id: 1,
name: "IceCream",
details: [{
id: "12",
name: "milk",
quantity: "50",
rate: "100"
},
{
id: "13",
name: "cream",
quantity: "50",
rate: "300"
}
]
},
{
id: 2,
name: "Coffee",
details: [{
id: "14",
name: "Coffee bean",
quantity: "60",
rate: "200"
},
{
id: "15",
name: "water",
quantity: "60",
rate: "300"
}
]
},
{
id: 3,
name: "Tea",
details: [{
id: "16",
name: "Tea leaf",
quantity: "50",
rate: "700"
}]
}
]
let Array2 = [{
id: 1,
name: "IceCream",
details: [{
id: "12",
name: "milk",
quantity: "50",
rate: "500"
},
{
id: "13",
name: "cream",
quantity: "50",
rate: "700"
}
]
},
{
id: 2,
name: "Coffee",
details: [{
id: "14",
name: "Coffee bean",
quantity: "60",
rate: "800"
},
{
id: "15",
name: "water",
quantity: "60",
rate: "8000"
}
]
}
]
Array1 = Array1.map(item => {
let element = Array2.find(e => e.id == item.id);
if (element) {
item.details = item.details.map(e => {
let detail = element.details.find(d => d.id == e.id);
if (detail)
e.rate = detail.rate;
return e;
});
}
return item;
});
console.log(Array1);
Make a map of Array2's items (by id) and each of Array2's details (by id), and then you can iterate over Array1 and mutate its properties with low complexity:
const items2ById = {};
for (const item of Array2) {
items2ById[item.id] = item;
}
const items2DetailsById = {};
for (const detail of Array2.flatMap(({ details }) => details)) {
items2DetailsById[detail.id] = detail;
}
for (const item of Array1) {
if (!items2ById[item.id]) continue;
for (const detail of item.details) {
if (items2DetailsById[detail.id]) {
detail.rate = items2DetailsById[detail.id].rate;
}
}
}
Note that since you're mutating the existing objects, .map isn't really appropriate, since you don't really care to create a new array - instead, just iterate over the array and mutate it as needed.
let Array1 = [{
id: 1,
name: "IceCream",
details: [{
id: "12",
name: "milk",
quantity: "50",
rate: "100"
},
{
id: "13",
name: "cream",
quantity: "50",
rate: "300"
}
]
},
{
id: 2,
name: "Coffee",
details: [{
id: "14",
name: "Coffee bean",
quantity: "60",
rate: "200"
},
{
id: "15",
name: "water",
quantity: "60",
rate: "300"
}
]
},
{
id: 3,
name: "Tea",
details: [{
id: "16",
name: "Tea leaf",
quantity: "50",
rate: "700"
}]
}
]
let Array2 = [{
id: 1,
name: "IceCream",
details: [{
id: "12",
name: "milk",
quantity: "50",
rate: "500"
},
{
id: "13",
name: "cream",
quantity: "50",
rate: "700"
}
]
},
{
id: 2,
name: "Coffee",
details: [{
id: "14",
name: "Coffee bean",
quantity: "60",
rate: "800"
},
{
id: "15",
name: "water",
quantity: "60",
rate: "8000"
}
]
}
];
const items2ById = {};
for (const item of Array2) {
items2ById[item.id] = item;
}
const items2DetailsById = {};
for (const detail of Array2.flatMap(({ details }) => details)) {
items2DetailsById[detail.id] = detail;
}
for (const item of Array1) {
if (!items2ById[item.id]) continue;
for (const detail of item.details) {
if (items2DetailsById[detail.id]) {
detail.rate = items2DetailsById[detail.id].rate;
}
}
}
console.log(Array1);

display countries based on selection of id from a complex JSON structure using Javascript Map or Filter Method

I have a JSON structure which is bit complex and I want to display the corresponding items based on the selection of Id. For example, in my JSON structure I have the sections of continent and under each continent countries are listed within the property names "Levels".So, I want to filter each continent based on the id from the "Levels" property.
So, if the "Country.Level.Id === 6" it should display the Country.Name="America". I have been trying to make it work by using JavaScript Map and Filter method but couldn't make it work.
Here is my SandBox Link: https://codesandbox.io/s/dark-feather-ugvxv?file=/src/index.js:0-1294
The data:
const items = [
{
Country: [
{
Id: "1",
Name: "Europe",
Levels: [
{
Id: "1",
Name: "Finland",
DisplayName: "Finland"
}
]
},
{
Id: "1",
Name: "ASIA",
Levels: [
{
Id: "2",
Name: "Bangladesh",
DisplayName: "Bangladesh"
},
{
Id: "3",
Name: "India",
DisplayName: "India"
},
{
Id: "4",
Name: "Pakistan",
DisplayName: "Pakistan"
}
]
},
{
Id: "3",
Name: "America",
Levels: [
{
Id: "5",
Name: "USA",
DisplayName: "USA"
},
{
Id: "6",
Name: "Canada",
DisplayName: "Canada"
},
{
Id: "7",
Name: "Australia",
DisplayName: "Australia"
}
]
},
{
Id: "4",
Name: "Africa",
DisplayName: "Africa",
Levels: [
{
Id: "8",
Name: "Nigeria",
DisplayName: "Nigeria"
}
]
}
]
}
];
My coding attempt:
const selectById = "5";
const countries = items[0].Country;
const result = countries.filter(item => item.Levels.Id === selectById);
console.log(result);
According to your data structure, this function will find a continent from a country id:
function findContinentByCountryId(items, id) {
return items[0].Country.find((continent) => {
return continent.Levels.some(country => country.Id === id)
})
}
You can test it with the snippet below:
function findContinentByCountryId(items, id) {
return items[0].Country.find((continent) => {
return continent.Levels.some(country => country.Id === id)
})
}
<form>
<label for="country-id">Country id:</label>
<input id="country-id">
<input type="submit" value="Find continent by country id">
</form>
<span></span>
<script>
const items = [
{
Country: [
{
Id: "1",
Name: "Europe",
Levels: [
{
Id: "1",
Name: "Finland",
DisplayName: "Finland"
}
]
},
{
Id: "1",
Name: "ASIA",
Levels: [
{
Id: "2",
Name: "Bangladesh",
DisplayName: "Bangladesh"
},
{
Id: "3",
Name: "India",
DisplayName: "India"
},
{
Id: "4",
Name: "Pakistan",
DisplayName: "Pakistan"
}
]
},
{
Id: "3",
Name: "America",
Levels: [
{
Id: "5",
Name: "USA",
DisplayName: "USA"
},
{
Id: "6",
Name: "Canada",
DisplayName: "Canada"
},
{
Id: "7",
Name: "Australia",
DisplayName: "Australia"
}
]
},
{
Id: "4",
Name: "Africa",
DisplayName: "Africa",
Levels: [
{
Id: "8",
Name: "Nigeria",
DisplayName: "Nigeria"
}
]
}
]
}
];
const form = document.querySelector('form')
const input = document.querySelector('input')
const result = document.querySelector('span')
form.addEventListener('submit', (event) => {
event.preventDefault()
const continent = findContinentByCountryId(items, input.value)
result.textContent = continent ? continent.Name : 'Continent not found'
})
</script>
Side note
I don't know the context of your problem, but be aware that object properties are usually camelCased in javascript (instead of PascalCased in your case) and that Country and Levels might not be ideal names for the corresponding data. Furthermore, in case this wasn't intentional, Europe and Asia have the same id in your dataset.
You have to change your filter method appropriately it'll work
countries.filter(item => item.Levels.find(elem => elem.Id === selectById))
SandboxLink

Sum column tabulator based on condition

I am trying to sum column value in tabulator with specific condition and follow this Custom Calculation Function
What I tried so far:
$(document).ready(function() {
function getSum(total, num) {
return total + num;
}
var adultCalc = function(values, data, calcParams) {
var tempvalue = [];
data.forEach(function(data) {
var count = data.age * data.qty;
tempvalue.push(count);
});
console.log('array', tempvalue);
console.log('total', tempvalue.reduce(getSum));
/*return tempvalue;*/
}
var tabledata = [{
id: 1,
name: "Oli Bob",
age: "12",
qty: "1",
dob: ""
},
{
id: 3,
name: "Christine Lobowski",
age: "42",
qty: "1",
dob: "22/05/1982"
},
{
id: 4,
name: "Brendon Philips",
age: "35",
qty: "2",
dob: "01/08/1980"
},
{
id: 5,
name: "Margret Marmajuke",
age: "16",
qty: "0",
dob: "31/01/1999"
},
{
id: 5,
name: "Marmajuke",
age: "17",
qty: "0",
dob: "31/01/1999"
},
{
id: 4,
name: "Philips",
age: "27",
qty: "0",
dob: "01/08/1980"
}
];
var table = new Tabulator("#example-table", {
height: 205,
data: tabledata,
layout: "fitColumns",
columns: [{
title: "Name",
field: "name",
width: 150
},
{
title: "Age",
field: "age",
bottomCalc: adultCalc
},
{
title: "Qty",
field: "qty"
},
{
title: "Date Of Birth",
field: "dob",
sorter: "date",
align: "center"
}
]
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link href="https://unpkg.com/tabulator-tables#4.1.4/dist/css/tabulator.min.css" rel="stylesheet">
<script type="text/javascript" src="https://unpkg.com/tabulator-tables#4.1.4/dist/js/tabulator.min.js"></script>
<div id="example-table"></div>
My formula is : age * qty push it into array and total it.
I'm success to get the value what i want and push it into array, but the problem is i can't sum the array with array reduce function.
I got this error
TypeError: reduce of empty array with no initial value
My problem just to get total sum of array.
Can someone tell me what's wrong with my code?
Thanks.
You need to provide initial value to reduce
console.log('total', tempvalue.reduce(getSum,0));
first time when you use reduce you have an empty array and which is causing reduce to produce an error. you can pass initial value and it should work as expected.
Note: If initialValue isn't provided, reduce() will execute the
callback function starting at index 1, skipping the first index. If
initialValue is provided, it will start at index 0.
$(document).ready(function() {
function getSum(total, num) {
return total + num;
}
var adultCalc = function(values, data, calcParams) {
var tempvalue = [];
data.forEach(function(data) {
var count = data.age * data.qty;
tempvalue.push(count);
});
console.log('array', tempvalue);
console.log('total', tempvalue.reduce(getSum,0));
/*return tempvalue;*/
}
var tabledata = [{
id: 1,
name: "Oli Bob",
age: "12",
qty: "1",
dob: ""
},
{
id: 3,
name: "Christine Lobowski",
age: "42",
qty: "1",
dob: "22/05/1982"
},
{
id: 4,
name: "Brendon Philips",
age: "35",
qty: "2",
dob: "01/08/1980"
},
{
id: 5,
name: "Margret Marmajuke",
age: "16",
qty: "0",
dob: "31/01/1999"
},
{
id: 5,
name: "Marmajuke",
age: "17",
qty: "0",
dob: "31/01/1999"
},
{
id: 4,
name: "Philips",
age: "27",
qty: "0",
dob: "01/08/1980"
}
];
var table = new Tabulator("#example-table", {
height: 205,
data: tabledata,
layout: "fitColumns",
columns: [{
title: "Name",
field: "name",
width: 150
},
{
title: "Age",
field: "age",
bottomCalc: adultCalc
},
{
title: "Qty",
field: "qty"
},
{
title: "Date Of Birth",
field: "dob",
sorter: "date",
align: "center"
}
]
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link href="https://unpkg.com/tabulator-tables#4.1.4/dist/css/tabulator.min.css" rel="stylesheet">
<script type="text/javascript" src="https://unpkg.com/tabulator-tables#4.1.4/dist/js/tabulator.min.js"></script>
<div id="example-table"></div>
It can be done even easier. And don't forget the second parameter (initial value) of Array.reduce method.
$(document).ready(function() {
function getSum(total, num) {
return total + num;
}
var adultCalc = function(values, data, calcParams) {
return data.map(function(d) {
return d.age * d.qty;
})
.reduce(getSum, 0);
}
//or even in ES6 style
const qtyCalc = (values, data, calcParams) =>
data.map(d => d.age * d.qty)
.reduce((t, n) => t + n * 2, 0);
var tabledata = [{
id: 1,
name: "Oli Bob",
age: "12",
qty: "1",
dob: ""
},
{
id: 3,
name: "Christine Lobowski",
age: "42",
qty: "1",
dob: "22/05/1982"
},
{
id: 4,
name: "Brendon Philips",
age: "35",
qty: "2",
dob: "01/08/1980"
},
{
id: 5,
name: "Margret Marmajuke",
age: "16",
qty: "0",
dob: "31/01/1999"
},
{
id: 5,
name: "Marmajuke",
age: "17",
qty: "0",
dob: "31/01/1999"
},
{
id: 4,
name: "Philips",
age: "27",
qty: "0",
dob: "01/08/1980"
}
];
var table = new Tabulator("#example-table", {
height: 205,
data: tabledata,
layout: "fitColumns",
columns: [{
title: "Name",
field: "name",
width: 150
},
{
title: "Age",
field: "age",
bottomCalc: adultCalc
},
{
title: "Qty",
field: "qty",
bottomCalc: qtyCalc
},
{
title: "Date Of Birth",
field: "dob",
sorter: "date",
align: "center"
}
]
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link href="https://unpkg.com/tabulator-tables#4.1.4/dist/css/tabulator.min.css" rel="stylesheet">
<script type="text/javascript" src="https://unpkg.com/tabulator-tables#4.1.4/dist/js/tabulator.min.js"></script>
<div id="example-table"></div>

How to get unique Id for multiple duplicate properties

say we have a object:
var db = [
{Id: "201" , Player: "Jon",price: "3.99", loc: "NJ" },
{Id: "202", Player: "Sam",price: "4.22", loc: "PA" },
{Id: "203" ,Player: "Sam",price: "4.22", loc: "NY" },
{Id: "204", Player: "Bill",price: "3.22", loc: "TX" },
{Id: "205" ,Player: "Dave",price: "3.99", loc: "WA" },
{Id: "206" ,Player: "Dave",price: "3.99", loc: "WI" },
];
202&203 and 205&206 have similar values for player and price but I need just one id for similar values i.e, output should be 202,205.
Can someone help me with that.
You could filter it with a hash table for look up for the same player and price values.
var db = [{ Id: "201", Player: "Jon", price: "3.99", loc: "NJ" }, { Id: "202", Player: "Sam", price: "4.22", loc: "PA" }, { Id: "203", Player: "Sam", price: "4.22", loc: "NY" }, { Id: "204", Player: "Bill", price: "3.22", loc: "TX" }, { Id: "205", Player: "Dave", price: "3.99", loc: "WA" }, { Id: "206", Player: "Dave", price: "3.99", loc: "WI" }],
filtered = db.filter(function (a) {
var key = a.Player + '|' + a.price;
if (!this[key]) {
this[key] = true;
return true;
}
}, Object.create(null))
console.log(filtered);
I think this could be a summarized answer:
var db = [{ Id: "201", Player: "Jon", price: "3.99", loc: "NJ" }, { Id: "202", Player: "Sam", price: "4.22", loc: "PA" }, { Id: "203", Player: "Sam", price: "4.22", loc: "NY" }, { Id: "204", Player: "Bill", price: "3.22", loc: "TX" }, { Id: "205", Player: "Dave", price: "3.99", loc: "WA" }, { Id: "206", Player: "Dave", price: "3.99", loc: "WI" }];
var result = db.filter((v, k) =>
(k = v.Player + v.price) in this ? false :(this[k] = true));
console.log(result);

Categories

Resources