I'm receiving the following data in my JS from a WebService :
{
"fire": {
"totalOccurence": 2,
"statsByCustomer": [
{
"idCustomer": 1,
"occurence": 1
},
{
"idCustomer": 2,
"occurence": 1
}
]
},
"flood": {
"totalOccurence": 1,
"statsByCustomer": [
{
"idCustomer": 1,
"occurence": 1
}
]
}
}
What's the fastest way to create the following object as a result :
{
"1": {
"fire": 1,
"flood": 1
},
"2": {
"fire": 1,
"flood": 0
}
}
I'm actually doing multiple forEach to format the data myself, but i think it's pretty ugly and not efficient..
PS : the key for the result map is the customer Id
Any idea on how to do this the right way?
Thanks for your help !
You could iterate the outer object's keys and then the inner arrays. If an result object does not exist, create one with the wanted keys and zero values.
var data = { fire: { totalOccurence: 2, statsByCustomer: [{ idCustomer: 1, occurence: 1 }, { idCustomer: 2, occurence: 1 }] }, flood: { totalOccurence: 1, statsByCustomer: [{ idCustomer: 1, occurence: 1 }] } },
result = {},
keys = Object.keys(data);
keys.forEach(function (k) {
data[k].statsByCustomer.forEach(function (a) {
if (!result[a.idCustomer]) {
result[a.idCustomer] = {};
keys.forEach(function (kk) {
result[a.idCustomer][kk] = 0;
});
}
result[a.idCustomer][k] += a.occurence;
});
});
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Related
I am having a little difficulty sorting an array of objects. At the moment I have a dataset like sorting
[
{
"index":"football",
"values":0.3,
"id":"1"
},
{
"index":"Unknown",
"values":0.5,
"id":"2"
},
{
"index":"golf",
"values":0.1,
"id":"3"
},
{
"index":"cricket",
"values":0.222,
"id":"4",
},
{
"index":"Other",
"values":0.333,
"id":"5"
},
{
"index":"netball",
"values":0.753,
"id":"6",
},
]
What I am trying to do is sort this based on their values, with the highest being on top. To do this, I done
myDataSet.sort((a, b) => parseFloat(b.values) - parseFloat(a.values));
This seems to work. However, it is the second part I am struggling with. Whatever order it sorts in I always need Other 2nd from bottom and Unknown bottom. So the above should turn into this
[
{
"index":"netball",
"values":0.753,
"id":"6",
},
{
"index":"football",
"values":0.3,
"id":"1"
},
{
"index":"cricket",
"values":0.222,
"id":"4",
},
{
"index":"golf",
"values":0.1,
"id":"3"
},
{
"index":"Other",
"values":0.333,
"id":"5"
},
{
"index":"Unknown",
"values":0.5,
"id":"2"
},
]
I tried using a filter, this seems to put them at the bottom but then the rest are no longer sorted
myDataSet.filter((e) => e.index === 'Other')
.filter((e) => e.index === 'Unknown')
.sort((a, b) => parseFloat(b.values) - parseFloat(a.values));
How can I sort based on their values but keep Other and Unknown at the bottom?
Thanks
I'd suggest creating a custom function to determine sort order, say getSortValue(), then using Array.sort():
let a = [ { "index":"football", "values":0.3, "id":"1" }, { "index":"Unknown", "values":0.5, "id":"2" }, { "index":"golf", "values":0.1, "id":"3" }, { "index":"cricket", "values":0.222, "id":"4", }, { "index":"Other", "values":0.333, "id":"5" }, { "index":"netball", "values":0.753, "id":"6", }, ]
function getSortValue(obj) {
const key = obj.index.toLowerCase();
return { "unknown": -2, "other": -1 }[key] || obj.values;
}
console.log(a.sort((a,b) => getSortValue(b) - getSortValue(a)));
.as-console-wrapper { max-height: 100% !important; top: 0; }
You could sort the array directly with an object for wanted order and a default value for all other unknown values.
Then use values directly without conversion.
const
data = [{ index: "netball", values: 0.753, id: "6" }, { index: "football", values: 0.3, id: "1" }, { index: "cricket", values: 0.222, id: "4" }, { index: "golf", values: 0.1, id: "3" }, { index: "Other", values: 0.333, id: "5" }, { index: "Unknown", values: 0.5, id: "2" }],
bottom = { Other: 1, Unknown: 2 };
data.sort((a, b) =>
(bottom[a.index] || 0) - (bottom[b.index] || 0) ||
b.values - a.values
);
console.log(data);
.as-console-wrapper { max-height: 100% !important; top: 0; }
my backend service send me list of node as an array. but I need is, each next node is value of its previous node(SEE EXAMPLE). I want whole list as nested object in singe object.
WHAT I HAVE:
[
{
"nodeId": 1,
},
{
"nodeId": 3,
},
{
"nodeId": 16,
}
]
WHAT I NEED:
[
{
"nodeId": 1,
"staticChild": [
{
"nodeId": 3,
"staticChild": [
{
"nodeId": 16,
}
]
}
]
}
]
You could reduce the array from the right side and build a new object with a staticChild property.
var array = [{ nodeId: 1 }, { nodeId: 3 }, { nodeId: 16 }],
result = array.reduceRight((a, b) => ({ ...b, staticChild: [a] }));
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Based on the input / output you provided, you can use a recursive funtion like :
const data = [{
nodeId: 1
},
{
nodeId: 3
},
{
nodeId: 16
}
];
const transform = data => {
const [node, ...rest] = data;
if (rest.length > 0) {
return {
...node,
staticChild: [transform(rest)]
};
} else {
return {
...node,
hasChildren: false
};
}
};
const result = transform(data);
console.log(result);
At first reverse the array and the make an iteration over the revered array using reduce() to make your desire format.
let data = [{"nodeId": 1},{"nodeId": 3},{"nodeId": 16}]
data = data.reverse().reduce((old, cur) => {
if (!old.length) {
old = [cur]
} else {
cur['staticChild'] = old
old = [cur]
}
return old
}, [])
console.log(data)
You can use the reduceRight() array method to perform the transformation.
const data = [{
"nodeId": 1,
},
{
"nodeId": 3,
},
{
"nodeId": 16,
}
]
const nested = data.reduceRight((acc, item) => {
return [ { ...item, staticChild: acc } ]
}, []);
console.log(nested);
Or more succinctly:
const nested = data.reduceRight((acc, item) => [ { ...item, staticChild: acc } ],[]);
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)
I have this following array
var array=[{ semster:1, name:Book1 }, { semster:1, name:Book2 }, { semster:2, name:Book4 }, { semster:3, name:Book5 }, { semster:3, name:Book6 }, { semster:4, name:Book7 }]
Now I want to sort my array to split the current array into chunks of array like following
var array=[[{ semster:1, name:Book1 }, { semster:1, name:Book2 }],[ { semster:2, name:Book4 }], [{ semster:3, name:Book5 }, { semster:3, name:Book6 }], [{ semster:4, name:Book7 }]]
I have tried to achieve this with following code :
function splitIntoSubArray(arr, count) {
var newArray = [];
while (arr.length > 0) {
newArray.push(arr.splice(0, count));
}
return newArray;
}
But this can only divide the array on the basis of fixed size. Any kind of suggestion is appreciated.
Thanks
You can simply use Array.reduce() to group items by semester. Object.values() on the map gives you the desired result.
var array=[{ semster:1, name:"Book1" }, { semster:1, name:"Book2" }, { semster:2, name:"Book4" }, { semster:3, name:"Book5" }, { semster:3, name:"Book6" }, { semster:4, name:"Book7" }];
var result = Object.values(array.reduce((a, curr)=>{
(a[curr.semster] = a[curr.semster] || []).push(curr);
return a;
},{}));
console.log(result);
You could reduce the array by checking the last group with the same semester.
var array = [{ semester: 1, name: 'Book1' }, { semester: 1, name: 'Book2' }, { semester: 2, name: 'Book4' }, { semester: 3, name: 'Book5' }, { semester: 3, name: 'Book6' }, { semester: 4, name: 'Book7' }],
grouped = array.reduce((r, o) => {
var last = r[r.length - 1];
if (last && last[0].semester === o.semester) {
last.push(o);
} else {
r.push([o]);
}
return r;
}, []);
console.log(grouped);
.as-console-wrapper { max-height: 100% !important; top: 0; }
How would you loop through provided JSON to get every grade from all the years and paste them in array?I'm quite new to JS so any explanation is welcome.
Expected array for this example would be [2,4,2,5,4,5,4.5,2,3.5,5,5,5,5,5]
{
"first_name": "Ala",
"last_name": "Kowalski",
"birth_date": "29 AUG 1990",
"indeks_number": "9454530",
"year_of_study": "2",
"courses": {
"2013": {
"AlgorithmsI": {
"grades": {
"exercices": [
2,
4
],
"lecture": [
2,
5
]
}
},
"BasicPhysicsI": {
"grades": {
"exercices": [
4
],
"lecture": [
5
]
}
},
"ProgrammingI": {
"grades": {
"exercices": [
4.5
],
"lecture": [
2,
3.5
]
}
}
},
"2014": {
"ProgrammingII": {
"grades": {
"exercices": [
5
],
"lecture": [
5
]
}
},
"BasicPhysicsII": {
"grades": {
"exercices": [
5
],
"lecture": [
5
]
}
},
"AlgorithmsII": {
"grades": {
"exercices": [
5
],
"lecture": [
5
]
}
}
}
}
}
I might use JSON.stringify as a way to iterate through the object:
grades = [];
JSON.stringify(obj, function(key, value) {
if (key === 'grades')
grades = grades.concat(value.exercices, value.lecture);
return value;
});
How this works
JSON.stringify is designed to convert an object into a JSON string. To do that, it iterates over all values in the object at all levels. It also provides the ability to specify a replacer parameter, which is a function called with each key/value pair it encounters. Here, we use the replacer not to control the stringification, but to get a chance to examine each key/value pair to see if the key is 'grades', and if so add those grades to the grades array. We have to return value so that JSON.stringify keeps iterating. The actual result from JSON.stringify is irrelevant and thrown away.
Hi you can try this one.
function looop(jsonob) {
var gradeArray = [];
for (years in jsonob.courses) {
for (lessons in jsonob.courses[years]) {
for (x in jsonob.courses[years][lessons].grades.exercices) {
gradeArray.push(jsonob.courses[years][lessons].grades.exercices[x]);
}
for (x in jsonob.courses[years][lessons].grades.lecture) {
gradeArray.push(jsonob.courses[years][lessons].grades.lecture[x]);
}
}
}
return gradeArray;
}
var grades = [];
var obj = <your Object>;
processObj(obj);
function processObj(obj) {
for (var n in obj) {
if (n=='exercices' || n=='lectures') {
for (var j=0;j<obj[n].length;j++) {
grades.push(obj[n][j]);
}
} else {
processObj(obj[n]);
}
}
}
Recursive:
function each(object, iterator) {
Object.keys(object).forEach(function (key) {
var value = object[key];
iterator(value, key);
});
}
function inArray(array, value) {
return array.indexOf(value) > -1;
}
function isPlainObject(value) {
return !!value && typeof value === 'object' && value.constructor === Object;
}
function getGrades(data) {
var grades = [];
each(data, function (value, key) {
if (inArray(['exercices', 'lecture'], key)) {
grades = grades.concat(value);
} else if (isPlainObject(value)) {
grades = grades.concat(getGrades(value));
}
});
return grades;
}
You can test this in Node.js with:
var assert = require('assert');
assert.deepEqual(getGrades(fixture),
[2, 4, 2, 5, 4, 5, 4.5, 2, 3.5, 5, 5, 5, 5, 5, 5]);
Where fixture is your JSON.