Distinct json object in JavaScript - javascript

I'm using spring boot and I generated a json object.
[
{"date":"2017-11-20T17:12:01.340","name":"abc","feedback":"good","category":"AA"},
{"date":"2017-11-20T17:12:01.340","name":"abc","feedback":"bad","category":"BB"},
{"date":"2017-11-20T17:12:01.340","name":"abc","feedback":"poor","category":"CC"}
{"date":"2017-12-15T16:53:02.042","name":"xyz","feedback":"very bad","category":"AA"}
{"date":"2017-12-15T16:53:02.042","name":"xyz","feedback":"nice","category":"XX"}
{"date":"2017-12-15T16:53:02.042","name":"xyz","feedback":"okey","category":"YY"}
]
I have to distinct the date and get a new json object like following
[
{"date":"2017-11-20T17:12:01.340", "name":"abc", "feedback_1":"good", "feedback_2":"bad", "feedback_3":"poor", "category_1":"AA", "category_2":"BB", "category_3":"CC"},
{"date":"2017-12-15T16:53:02.042", "name":"xyz", "feedback_1":"very bad", "feedback_2":"nice", "feedback_3":"poor", "category_1":"AA", "category_2":"XX", "category_3":"YY"}
]
I try to get this format in Java or JavaScript. I tried my best using online resources but I failed since I'm new to JavaScript, how can I solve it? Thanks in advance.

You can use array#reduce to create an object and add counter to keep record of frequency of your JSON and using this counter add feedback and category. After that remove the counter from your result.
var data = [ {"date":"2017-11-20T17:12:01.340","name":"abc","feedback":"good","category":"AA"}, {"date":"2017-11-20T17:12:01.340","name":"abc","feedback":"bad","category":"BB"}, {"date":"2017-11-20T17:12:01.340","name":"abc","feedback":"poor","category":"CC"}, {"date":"2017-12-15T16:53:02.042","name":"xyz","feedback":"very bad","category":"AA"}, {"date":"2017-12-15T16:53:02.042","name":"xyz","feedback":"nice","category":"XX"}, {"date":"2017-12-15T16:53:02.042","name":"xyz","feedback":"okey","category":"YY"} ];
var result = Object.values(data.reduce((r,o) => {
var key = o.data + "|" + o.name;
r[key] = r[key] || {date: o.date, name: o.name, count:1};
r[key] = Object.assign({}, r[key], {['feedback_'+r[key].count] : o.feedback, ['category_'+r[key].count]: o.category, count : r[key].count+1});
return r;
},{}));
result.forEach(o => delete o.count);
console.log(result);

take 2 array
1st array={"date":"2017-11-20T17:12:01.340","name":"abc","feedback":"good","category":"AA"},
{"date":"2017-11-20T17:12:01.340","name":"abc","feedback":"bad","category":"BB"},
{"date":"2017-11-20T17:12:01.340","name":"abc","feedback":"poor","category":"CC"}
2nd={"date":"2017-12-15T16:53:02.042","name":"xyz","feedback":"very bad","category":"AA"}
{"date":"2017-12-15T16:53:02.042","name":"xyz","feedback":"nice","category":"XX"}
{"date":"2017-12-15T16:53:02.042","name":"xyz","feedback":"okey","category":"YY"}
and use array_unique to get unique values

You can try linq.js library:
var data = [{"date":"2017-11-20T17:12:01.340","name":"abc","feedback":"good","category":"AA"}, {"date":"2017-11-20T17:12:01.340","name":"abc","feedback":"bad","category":"BB"}, {"date":"2017-11-20T17:12:01.340","name":"abc","feedback":"poor","category":"CC"}, {"date":"2017-12-15T16:53:02.042","name":"xyz","feedback":"very bad","category":"AA"}, {"date":"2017-12-15T16:53:02.042","name":"xyz","feedback":"nice","category":"XX"}, {"date":"2017-12-15T16:53:02.042","name":"xyz","feedback":"okey","category":"YY"}];
var temp = Enumerable.From(data).GroupBy("$.date").Select("{date: $.Key(), name: $.First().name, feedback: Enumerable.From($).Select('$.feedback').ToArray(), category: Enumerable.From($).Select('$.category').ToArray() }").ToArray();
for (var item of temp) {
for (var prop of ['feedback', 'category']) {
for (var x of item[prop])
item[prop + '_' + (item[prop].indexOf(x) + 1)] = x
delete item[prop];
}
}
console.log(temp);
<script src="https://cdnjs.cloudflare.com/ajax/libs/linq.js/2.2.0.2/linq.min.js"></script>

Related

How to add key and values to anobject by splitting a string inside the object

I have the following array:
[
{
“Key”: “CUST”,
“Segment”: “A;B;C;D;E”
}
]
I want to transform it to:
[
{
“Key”: “CUST”,
“Segment 1”: “A”,
“Segment 2”: “B”,
“Segment 3”: “C”,
“Segment 4”: “D”,
“Segment 5”: “E”
}
]
I need to dynamically create the key names based on how many ";" separated values I have in the string “Segment,” as that number can change. I know I will probably need to use Split and maybe Reduce, Map, and Extend, but I’m having a tough time figuring it out. Can someone help me with this? Thank you!
You can use split as you thought with forEach
object.forEach(item => {
item["Customer Security Segment"].split(";").forEach((segment, idx) => {
item[`Customer Security Segment ${idx + 1}`] = segment;
});
delete item["Customer Security Segment"]
});
Thank you all for your possible solutions! I was actually able to achieve what I was looking to do using the following code:
$.extend($[‘Customer Security Segment’].split(";").reduce((accum, curVal, index) => accum.extend({["Customer Security Segment " + (index + 1)]: curVal }), {}))
This would give me the new columns I was looking for. After that I could simply drop the orignal column for "Customer Security Segment.
You can achieve this by using Array.map() :
// Input array
const arr = [
{
Key: "CUST",
Segment: "A;B;C;D;E"
}
];
const res = arr.map((obj) => {
const resObj = {
Key: obj.Key
};
obj.Segment.split(';').forEach((item, index) => {
resObj['Segment ' + (index + 1)] = item
});
return resObj;
});
console.log(res);

How can I access to each field of a json object?

I have used csvtojson in order to write the csv data into a sql database, the object that the funcion return to have this structure:
var prueba = [
{'Aula;Capacidad': 'A10+11;112'},
{'Aula;Capacidad': 'A12;66' }
];
How can I acces to each field? I am trying to do console.log(prueba[0]["Capacidad"]) in order to see if it is running but it prints "undefined".
'Aula;Capacidad' is seen as a key, so you only can do the following:
console.log(prueba[0]["Aula;Capacidad])
which will write
A10+11;112
to the console.
Your properties are actually named 'Aula;Capacidad', meaning you'd need to use prueba[0]['Aula;Capacidad'] to get the value you are looking for.
This is what you need to iterate through the list of items:
var prueba = [{'Aula;Capacidad': 'A10+11;112'},{'Aula;Capacidad': 'A12;66' }];
for (var i = 0; i < prueba.length; i++) {
console.log(prueba[i]);
}
If you need to go deeper and iterate over every item properties:
var prueba = [{'Aula;Capacidad': 'A10+11;112'},{'Aula;Capacidad': 'A12;66' }];
for(var i = 0; i < prueba.length; i++) {
for(var p in prueba[0]) {
console.log(p, prueba[i][p]);
}
}
Your key you are looking up is in a composite key. So you would need to look it up with that composite key and than split it.
var prueba = [
{'Aula;Capacidad': 'A10+11;112'},
{'Aula;Capacidad': 'A12;66' }
];
console.log(prueba[0]['Aula;Capacidad'].split(";")[1]);
Other choice is to parse it all and look it up by the key.
var prueba = [
{'Aula;Capacidad': 'A10+11;112'},
{'Aula;Capacidad': 'A12;66' }
];
const parsed = prueba.reduce(function (arr, row) {
const entry = Object.entries(row)[0];
const keys = entry[0].split(";");
const values = entry[1].split(";");
const data = keys.reduce(function (o, key, index) {
o[key] = values[index];
return o;
}, {});
arr.push(data);
return arr;
}, []);
console.log(parsed[0].Capacidad);
console.log(parsed[1].Capacidad);
Your data looks malformed so you might need to do some manual processing.
You have an array of two items, both with a single key-value in them. You can do console.log(prueba[0]["Aula;Capacidad"]) and this will return 'A10+11;112'.
You might need to split things by the ; there so you could do something like this:
var prueba = [
{'Aula;Capacidad': 'A10+11;112'},
{'Aula;Capacidad': 'A12;66' }
];
prueba.forEach(item => {
const splitItem = item["Aula;Capacidad"].split(";");
console.log("Each item now looks like this: " + splitItem)
// You can access the first and second part of the item like this
console.log(splitItem[0], splitItem[1])
})
To be honest, I'd go back and look at how this data is being added to your DB. It looks messed up.

Getting total value of same id and display the final answer as an json array using angularjs

I have a Json array as follows
$scope.array = [{id:"1", tot:20},{id:"2", tot:30},{id:"1", tot:20},{id:"3", tot:50}];
I want to get the sum of tot belonging to same id and display the final answer as another Json array as follows
output:
[{id:"1", total:40},{id:"2", total:30},{id:"3", total:50}]
How can I achieve this using angularjs?
I'd solve this by using Array.reduce. Like this:
var array = [{id:"1", tot:20},{id:"2", tot:30},{id:"1", tot:20},{id:"3", tot:50}];
var res = array.reduce(function (agg, obj) {
var objForId = agg.filter(function (idObj) { return idObj.id === obj.id})[0]
if (objForId) {
objForId.total += obj.tot;
} else {
agg.push({
id: obj.id,
total: obj.tot
})
}
return agg;
}, [])
console.log(res)

JavaScript Reduce array on timestamp

I am trying to reduce this array based on the timestamp:
Var Data = [{"Group":"OPS","Date":"2017-04-18T00:00:00.000Z","Count":1},{"Group":"BOE","Date":"2017-04-19T00:00:00.000Z","Count":1},{"Group":"EDW","Date":"2017-04-21T00:00:00.000Z","Count":1},{"Group":"SUPPORT","Date":"2017-04-17T00:00:00.000Z","Count":1},{"Group":"EDWEXTRACTS","Date":"2017-04-17T00:00:00.000Z","Count":1},{"Group":"EDWEXTRACTS","Date":"2017-04-18T00:00:00.000Z","Count":1},{"Group":"SAFTT","Date":"2017-04-17T00:00:00.000Z","Count":1},{"Group":"SAFTT","Date":"2017-04-18T00:00:00.000Z","Count":2},{"Group":"SAFTT","Date":"2017-04-21T00:00:00.000Z","Count":1},{"Group":"OPS","Date":"2017-04-17T00:00:00.000Z","Count":1},{"Group":"VIEW","Date":"2017-04-17T00:00:00.000Z","Count":1},{"Group":"VIEW","Date":"2017-04-19T00:00:00.000Z","Count":3}]
I have tried to use the reduce method but seem to be doing something wrong.
var obj = {}
result.reduce(function(r, e) {
if (!obj[e.Date]) {
obj[e.Date] = {
Date: e.Date,
Assest: []
}
r.push(obj[e.Date])
}
obj[e.Date].Date.push(e.Group)
obj[e.Date].Date.push(e.Count)
return r
}, [])
console.log(JSON.stringify(result, 0, 4))
My desired outcome would be:
Var New_Data = [{"Date":"xx/xx/xx", "Assets":[{"group":"XXX"},{"Count":"X"}]},{"Date":"xx/xx/xx","Assets":[{"group":"XXX"},{"Count":"X"}]}]
Any Idea how I can achieve this, any help would be great.
Thanks =)
The code below is a working example. With this in hand you should be able to alter it to your exact specifications, if they differ from what I have implemented.
var Data = [
{"Group":"OPS","Date":"2017-04-18T00:00:00.000Z","Count":1},
{"Group":"BOE","Date":"2017-04-19T00:00:00.000Z","Count":1},
{"Group":"EDW","Date":"2017-04-21T00:00:00.000Z","Count":1},
{"Group":"SUPPORT","Date":"2017-04-17T00:00:00.000Z","Count":1},
{"Group":"EDWEXTRACTS","Date":"2017-04-17T00:00:00.000Z","Count":1},
{"Group":"EDWEXTRACTS","Date":"2017-04-18T00:00:00.000Z","Count":1},
{"Group":"SAFTT","Date":"2017-04-17T00:00:00.000Z","Count":1},
{"Group":"SAFTT","Date":"2017-04-18T00:00:00.000Z","Count":2},
{"Group":"SAFTT","Date":"2017-04-21T00:00:00.000Z","Count":1},
{"Group":"OPS","Date":"2017-04-17T00:00:00.000Z","Count":1},
{"Group":"VIEW","Date":"2017-04-17T00:00:00.000Z","Count":1},
{"Group":"VIEW","Date":"2017-04-19T00:00:00.000Z","Count":3}
];
Data = Data.reduce(function(r, e) {
var date = e.Date.match(/(\d+-\d+-\d+)/)[0].replace(/-/g, '/');
if (r[date] == undefined) {
r[date] = {Date: date, Assets: []};
}
r[date].Assets.push({Group: e.Group});
r[date].Assets.push({Count: e.Count});
return r
}, {});
console.log(Data);
You may need to convert the resulting object into an array:
new_data = [];
for(i in Data){
new_data.push(Data[i]);
}
What you need is something like this?
var result = dados.map(function (v) {
return {
Date: new Date(v["Date"]),
Assets: [
{Group: v['Group']},
{Count: v['Count']}
]
};
});
or Do you need to create a group?

Flattening json such that one property is key and the other value

I have data in following format..
var array = [{"name":"abc","boss":"def","sub":[{"schema":"a","data":1},{"schema":"b","data":0},{"schema":"c","data":0}]},
.
.
.
]
I wish to transform it to the following structure:
[{"name":"abc","boss":"def","a":1,"b":0,"c":0},
.
.
.
]
Based on the answer here.. I tried..
grouped = [];
array.forEach(function (a) {
if (!this[a.name]||!this[a.boss]) {
this[a.name] = { name: a.name, boss:a.boss };
grouped.push(this[a.name]);
}
this[a.name][a.sub.schema] = (this[a.name][a.sub.schema] || 0) + a.sub.data;
}, Object.create(null));
console.log(grouped);
The above gives undefined:NaN as the third property in the result objects..
Any help is sincerely appreciated.
Thanks
You probably want to reduce the sub object to properties of the item.
The following code maps the items in array to a new array, which contains the flattened items:
array = array.map(function(item) {
item = item.sub.reduce(function(x,y) { return x[y.schema] = y.data, x; }, item);
delete item.sub;
return item;
});
Try this simply.
var arr = [];
array.forEach(function(ele){
var obj = {};obj.name=ele.name;
obj.boss=ele.boss;
ele.sub.forEach(function(e){
obj[e.schema] = e.data
});
arr.push(obj)
});

Categories