Trying to change/match JSON object - javascript

I figure I shouldn't be having trouble with this, but I am. I am trying to switch up the syntax/variables of a JSON object to match a certain parameters.
Here is the JSON I am working with:
{
"name":"BHPhotovideo",
"prices":[
{
"price":"799.00",
"createdAt":"2017-07-23T16:17:11.000Z",
"updatedAt":"2017-07-23T17:21:41.000Z"
},
{
"price":"770.00",
"createdAt":"2017-07-21T16:17:11.000Z",
"updatedAt":"2017-07-23T16:17:11.000Z"
},
{
"price":"599.00",
"createdAt":"2017-07-19T16:17:11.000Z",
"updatedAt":"2017-07-22T16:17:11.000Z"
},
{
"price":"920.00",
"createdAt":"2017-07-22T16:17:11.000Z",
"updatedAt":"2017-07-22T16:17:11.000Z"
}
]
},
etc...
I am just trying to get the data to be formatted like this:
{
"label":"BHPhotoVideo", // Same as name
"data":[
{
"x":"2017-07-23T16:17:11.000Z", // Same as createdAt
"y":799 // Same as price
},
{
"x":"2017-07-21T16:17:11.000Z",
"y":770
},
{
"x":"2017-07-19T16:17:11.000Z",
"y":599
},
{
"x":"2017-07-22T16:17:11.000Z",
"y":920
}
]
},
etc...
The amount of these objects are dynamic/subject to change, I've been making a mess out of foreach loops and trying to piece this together. I keep coming into errors, what's the best way to approach this?

What about this ?
data.map(
(item) => ({
"label":"BHPhotoVideo", // Same as name
"data": item.prices.map(nested => ( {
"x":nested.createdAt,
"y":nested.price
}))
})
)

Did you want the y values to be integers?
var ar = [
{
"name":"BHPhotovideo",
"prices":[
{
"price":"799.00",
"createdAt":"2017-07-23T16:17:11.000Z",
"updatedAt":"2017-07-23T17:21:41.000Z"
},
{
"price":"770.00",
"createdAt":"2017-07-21T16:17:11.000Z",
"updatedAt":"2017-07-23T16:17:11.000Z"
},
{
"price":"599.00",
"createdAt":"2017-07-19T16:17:11.000Z",
"updatedAt":"2017-07-22T16:17:11.000Z"
},
{
"price":"920.00",
"createdAt":"2017-07-22T16:17:11.000Z",
"updatedAt":"2017-07-22T16:17:11.000Z"
}
]
},
{
"name":"Adorama",
"prices":[
{
"price":"799.00",
"createdAt":"2017-07-22T16:17:11.000Z",
"updatedAt":"2017-07-23T17:21:41.000Z"
},
{
"price":"799.00",
"createdAt":"2017-07-20T16:17:11.000Z",
"updatedAt":"2017-07-23T16:17:11.000Z"
},
{
"price":"810.00",
"createdAt":"2017-07-18T16:17:11.000Z",
"updatedAt":"2017-07-22T16:17:11.000Z"
},
{
"price":"799.00",
"createdAt":"2017-07-17T16:17:11.000Z",
"updatedAt":"2017-07-22T16:17:11.000Z"
}
]
}
];
var out = ar.map( function(a) {
return {
"label" : a.name,
"prices" : a.prices.map( function(aa) { return {x: aa.createdAt, y: aa.price} })
}
});
console.log( out );

map over the original array returning a changed object; returning the name, and a new array from using map over the prices.
const obj2 = obj.map((item) => {
return {
label: item.name,
data: item.prices.map((data) => {
return {
x: data.createdAt,
y: data.price
}
})
}
});
DEMO

Related

sort an array of object accoring to the values

I have this array of objects:
const array =[
{ a: 'good car' },
{ a: 'good car1' },
{ a: 'good car2' },
{ a: 'good car3' },
{ a: 'good car4' },
{ b: 'good car1' }
];
I need to sort it via values except in the case of ties. In the case of ties, the key is used to break the tie. I searched A LOT but couldn't use the answers as my keys in objects are not the same and also in case of the tie (values are the same), I cannot handle that.
Any suggestions?
You could get the entries, pick the first one and destructure it to key and value and take the same for the other object, then return the chained sorting values.
var array = [{ v21: 'sad sdd' }, { aaa: 'sad sdd' }, { v11: 'r err rr' }, { hf32: 'erwwer fgh' }, { z3f2: 'agfrr vbbar' }, { t142: 'gggoog anfa' }, { u23: 'fa handle err' }];
array.sort((a, b) => {
var [keyA, valueA] = Object.entries(a)[0],
[keyB, valueB] = Object.entries(b)[0];
return valueA.localeCompare(valueB) || keyA.localeCompare(keyB);
});
console.log(array);
.as-console-wrapper { max-height: 100% !important; top: 0; }
use sort from es6.
try this code:
const array =[
{ v21: 'sad sdd' },
{ v11: 'r err rr' },
{ hf32: 'erwwer fgh' },
{ z3f2: 'agfrr vbbar' },
{ t142: 'agfrr vbbar' },
{ u23: 'fa handle err' }
]
array.sort( (x,y) => {
if ( Object.values(x)[0] > Object.values(y)[0] )
return 1
else if ( Object.values(x)[0] < Object.values(y)[0] )
return -1
else {
if ( Object.keys(x)[0] > Object.keys(y)[0] )
return 1
else if ( Object.keys(x)[0] < Object.keys(y)[0] )
return -1
}
})
You can try the following code:
const array =[
{ v21: 'sad sdd' },
{ v11: 'r err rr' },
{ hf32: 'erwwer fgh' },
{ z3f2: 'agfrr vbbar' },
{ z3f1: 'agfrr vbbar' },
{ t142: 'gggoog anfa' },
{ u23: 'fa handle err' }
];
array.sort((a,b) => {
if (a[Object.keys(a)[0]] === b[Object.keys(b)[0]]) {
return Object.keys(a)[0].localeCompare(Object.keys(b)[0]);
}
return a[Object.keys(a)[0]].localeCompare(b[Object.keys(b)[0]]);
});
console.log(array);
A variant without using compare function:
const array = [
{ v21: "sad sdd" },
{ v11: "r err rr" },
{ hf32: "erwwer fgh" },
{ z3f2: "sad sdd" },
{ t142: "gggoog anfa" },
{ u23: "fa handle err" }
];
const result = array
.map(item => ({
key: Object.keys(item)[0],
value: item[Object.keys(item)[0]]
}))
.map(item => `${item.value}:${item.key}`)
.sort()
.map(item => item.split(":"))
.map(item => ({ [item[1]]: item[0] }));
console.log(result);
have to use maybe some other join char instead of ':' if it is expected in the value

Distinct Dates with its highest value from an object with javascript

I have something like this:
data = [
{
DateMeasured:"2018-08-27T04:46:25",
Steps:100
},
{
DateMeasured:"2018-08-27T04:46:25",
Steps:500
},
{
DateMeasured:"2018-08-27T04:46:25",
Steps:800
},
{
DateMeasured:"2018-08-26T04:46:25",
Steps:400
},
{
DateMeasured:"2018-08-26T04:46:25",
Steps:300
},
{
DateMeasured:"2018-08-25T04:46:25",
Steps:100
}
];
I have an object of data like above, now I want to recreate object with discrict dates but its highest steps, but now i want like this:
data = [
{
DateMeasured:"2018-08-27T04:46:25",
Steps:800
},
{
DateMeasured:"2018-08-26T04:46:25",
Steps:400
},
{
DateMeasured:"2018-08-25T04:46:25",
Steps:100
}
];
How can I achieve this goal?
You could reduce the array by checking the last inserted object with the same date and if not found, insert the object, otherwise check the value and update the array with a greater Step property.
var data = [{ DateMeasured: "2018-08-27T04:46:25", Steps: 100 }, { DateMeasured: "2018-08-27T04:46:25", Steps: 500 }, { DateMeasured: "2018-08-27T04:46:25", Steps: 800 }, { DateMeasured: "2018-08-26T04:46:25", Steps: 400 }, { DateMeasured: "2018-08-26T04:46:25", Steps: 300 }, { DateMeasured: "2018-08-25T04:46:25", Steps: 100 }],
result = data.reduce((r, o) => {
var index = r.findIndex(({ DateMeasured }) => DateMeasured === o.DateMeasured);
if (index === -1) {
r.push(o);
return r;
}
if (r[index].Steps < o.Steps) {
r[index] = o;
}
return r;
}, []);
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
If you need to sort by the number of steps and take the first 3 elements:
const data = [ { DateMeasured:"2018-08-27T04:46:25", Steps:100 }, { DateMeasured:"2018-08-27T04:46:25", Steps:500 }, { DateMeasured:"2018-08-27T04:46:25", Steps:800 }, { DateMeasured:"2018-08-26T04:46:25", Steps:400 }, { DateMeasured:"2018-08-26T04:46:25", Steps:300 }, { DateMeasured:"2018-08-25T04:46:25", Steps:100 } ];
const sorted = data.sort((a, b) => b.Steps - a.Steps)
const takeFirst3 = sorted.slice(0, 3)
console.log(takeFirst3)

Group an array on an attribute and make that attribut a parent array

With An example, I'm basically trying to go from :
[
{
'a':a1,
'b':b2
},
{
'a':a1,
'b':b5
},
{
'a':a3,
'b':b4
}
]
To :
[
{
'group':'a1',
'content':[
{
'a':a1,
'b':b2
},
{
'a':a1,
'b':b5
}
],
},
{
'group':'a3',
'content':[
{
'a':a3,
'b':b4
}
]
}
]
So in word reformat the array and group elements on an attribute, here a
There is a simple way by using lodash GroupBy
https://lodash.com/docs#groupBy
_.groupBy([
{
'a':"a1",
'b':"b2"
},
{
'a':"a1",
'b':"b5"
},
{
'a':"a3",
'b':"b4"
}
], "a")
The first arguments the array you want to group, an the second is the iterator you want to group, the result will be grouped in a array, it will not have the content preoperty.
{
"a1":[
{
"a":"a1",
"b":"b2"
},
{
"a":"a1",
"b":"b5"
}
],
"a3":[
{
"a":"a3",
"b":"b4"
}
]
}
See if this helps get you going, if not, let me know
If you only want that grouped array then you can achieve using reducer.
`let group = data.reduce((r, a) => {
r[a.a] = [...r[a.a] || [], a];
return r;
}, {});`
var data = [
{
'a':'a1',
'b':'b2'
},
{
'a':'a1',
'b':'b5'
},
{
'a':'a3',
'b':'b4'
}
]
let group = data.reduce((r, a) => {
r[a.a] = [...r[a.a] || [], a];
return r;
}, {});
console.log("group", group);

Creating result array based on 2 arrays using JavaScript ES6 Reduce method

Hi actually i have two arrays ( services and offer) and i'm trying connect offer array with service array based on service id using reduce method and i tried different method but nothing working i'm not able to solve this check my js fiddle link (not able to connect with offer array). please help me to resolve this. thanks in advance
const services = [
{
cid:1,
catname:'Facial',
services:[
{
sid:30,
sname:'Fruit facial'
},
{
sid:33,
sname:'Herbal facial'
}
]
},
{
cid:2,
catname:'Massage',
services:[
{
sid:40,
sname:'Head Massage'
},
{
sid:45,
sname:'Back Massage'
},
{
sid:46,
sname:'Face Massage'
}
]
}
]
Offer Array - here based on service id (sid) i want to connect with services array and create new array
const offer = [
{
offid:1,
sid:'33,40'
offvalue : 10%
},
{
offid:2,
sid:'45,46',
offvalue : 100
}
]
Expecting Result:
const Result = [
{
cid:1,
catname:'Facial',
services:[
{
sid:30,
sname:'Fruit facial'
},
{
sid:33,
sname:'Herbal facial',
offid:1,
offvalue : 10%
}
]
},
{
cid:2,
catname:'Massage',
services:[
{
sid:40,
sname:'Head Massage',
offid:1,
offvalue : 10%
},
{
sid:45,
sname:'Back Massage',
offid:2,
offvalue : 100
},
{
sid:46,
sname:'Face Massage',
offid:2,
offvalue : 100
}
]
}
]
If you can use ES6 features, then this should work:
const services = [{
cid:1,
catname:'Facial',
services: [{
sid:30,
sname:'Fruit facial'
}, {
sid:33,
sname:'Herbal facial'
}],
}, {
cid:2,
catname:'Massage',
services: [{
sid:40,
sname:'Head Massage'
}, {
sid:45,
sname:'Back Massage'
}, {
sid:46,
sname:'Face Massage'
}],
}];
const offer = [{
offid:1,
sid:'33,40',
offvalue : "10%"
}, {
offid:2,
sid:'45,46',
offvalue : "100"
}];
const result = services.map(val => {
return {
...val,
services: val.services.map(serv => {
// Here is where we find any matching offers, then add their data to the service.
const off = offer.find(x => x.sid.split(",").includes(String(serv.sid)));
if (off) {
serv.offid = off.offid;
serv.offvalue = off.offvalue;
}
return serv;
}),
}
});
console.log(result);

Array of objects, combine values where key matches. with Underscore

Given the following array:
[
{
"real":104.1530776708426,
"workHour":8,
"value":null
},
{
"real":71.53948769310401,
"workHour":9
},
{
"real":97.84076993321577,
"workHour":10
},
{
"real":115.72564185649178,
"workHour":11
},
{
"real":79.95589800993977,
"workHour":12
},
{
"real":91.52846219558896,
"workHour":13
},
{
"real":57.86282092824589,
"workHour":14
},
{
"real":148.33923183423036,
"workHour":15
},
{
"real":125.19410346293202,
"workHour":16
},
{
"real":67.33128253468612,
"workHour":17
},
{
"real":55.75871834903695,
"workHour":18
},
{
"real":102.04897509163365,
"workHour":19
},
{
"real":132.55846249016332,
"workHour":20
},
{
"real":138.87077022779013,
"workHour":21
},
{
"real":60,
"workHour":8
},
{
"real":52,
"workHour":9
},
{
"real":114,
"workHour":10
},
{
"real":115,
"workHour":11
},
{
"real":92,
"workHour":12
},
{
"real":102,
"workHour":13
},
{
"real":54,
"workHour":14
},
{
"real":62,
"workHour":15
},
{
"real":133,
"workHour":16
},
{
"real":116,
"workHour":17
},
{
"real":106,
"workHour":18
},
{
"real":115,
"workHour":19
},
{
"real":115,
"workHour":20
},
{
"real":125,
"workHour":21
}
]
How can I find where the workHour match, and combine real there?
I did it with pure JS
const array = [{"real":104.1530776708426,"workHour":8,"value":null},{"real":71.53948769310401,"workHour":9},{"real":97.84076993321577,"workHour":10},{"real":115.72564185649178,"workHour":11},{"real":79.95589800993977,"workHour":12},{"real":91.52846219558896,"workHour":13},{"real":57.86282092824589,"workHour":14},{"real":148.33923183423036,"workHour":15},{"real":125.19410346293202,"workHour":16},{"real":67.33128253468612,"workHour":17},{"real":55.75871834903695,"workHour":18},{"real":102.04897509163365,"workHour":19},{"real":132.55846249016332,"workHour":20},{"real":138.87077022779013,"workHour":21},{"real":60,"workHour":8},{"real":52,"workHour":9},{"real":114,"workHour":10},{"real":115,"workHour":11},{"real":92,"workHour":12},{"real":102,"workHour":13},{"real":54,"workHour":14},{"real":62,"workHour":15},{"real":133,"workHour":16},{"real":116,"workHour":17},{"real":106,"workHour":18},{"real":115,"workHour":19},{"real":115,"workHour":20},{"real":125,"workHour":21}];
var map = {};
for (var i=0; i<array.length; i++) {
var obj = array[i],
id = obj.workHour;
if (id in map) { // we know this id already
// get the object and sum properties
map[id].real += obj.real;
} else // create a new one
map[id] = {
workHour: id,
real: obj.real,
};
}
console.log(map)
How can I do it with ES6? or Underscore?
Loop the array with Array#reduce to create a new object with combined values:
var data = [{"real":104.1530776708426,"workHour":8,"value":null},{"real":71.53948769310401,"workHour":9},{"real":97.84076993321577,"workHour":10},{"real":115.72564185649178,"workHour":11},{"real":79.95589800993977,"workHour":12},{"real":91.52846219558896,"workHour":13},{"real":57.86282092824589,"workHour":14},{"real":148.33923183423036,"workHour":15},{"real":125.19410346293202,"workHour":16},{"real":67.33128253468612,"workHour":17},{"real":55.75871834903695,"workHour":18},{"real":102.04897509163365,"workHour":19},{"real":132.55846249016332,"workHour":20},{"real":138.87077022779013,"workHour":21},{"real":60,"workHour":8},{"real":52,"workHour":9},{"real":114,"workHour":10},{"real":115,"workHour":11},{"real":92,"workHour":12},{"real":102,"workHour":13},{"real":54,"workHour":14},{"real":62,"workHour":15},{"real":133,"workHour":16},{"real":116,"workHour":17},{"real":106,"workHour":18},{"real":115,"workHour":19},{"real":115,"workHour":20},{"real":125,"workHour":21}];
var result = data.reduce(function(r, o) {
if (r[o.workHour]) {
r[o.workHour].real += o.real
} else {
r[o.workHour] = {
workHour: o.workHour,
real: o.real
}
}
return r;
}, {});
console.log(result);
Using lodash(/underscore), this uses _.reduce() with _.clone() to build an aggregate object. The values of this object are then output as an array of objects similar to your input array using _.values().
var data = [{"real":104.1530776708426,"workHour":8,"value":null},{"real":71.53948769310401,"workHour":9},{"real":97.84076993321577,"workHour":10},{"real":115.72564185649178,"workHour":11},{"real":79.95589800993977,"workHour":12},{"real":91.52846219558896,"workHour":13},{"real":57.86282092824589,"workHour":14},{"real":148.33923183423036,"workHour":15},{"real":125.19410346293202,"workHour":16},{"real":67.33128253468612,"workHour":17},{"real":55.75871834903695,"workHour":18},{"real":102.04897509163365,"workHour":19},{"real":132.55846249016332,"workHour":20},{"real":138.87077022779013,"workHour":21},{"real":60,"workHour":8},{"real":52,"workHour":9},{"real":114,"workHour":10},{"real":115,"workHour":11},{"real":92,"workHour":12},{"real":102,"workHour":13},{"real":54,"workHour":14},{"real":62,"workHour":15},{"real":133,"workHour":16},{"real":116,"workHour":17},{"real":106,"workHour":18},{"real":115,"workHour":19},{"real":115,"workHour":20},{"real":125,"workHour":21}];
var result = _.values(_.reduce(data, (sumObj, curr) => {
if (sumObj[curr.workHour])
sumObj[curr.workHour].real += curr.real;
else
sumObj[curr.workHour] = _.clone(curr);
return sumObj;
}, {}));
console.log(result);
.as-console-wrapper{top:0;max-height:100%!important;}
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js"></script>

Categories