manipulating JSON array data - javascript

I have a JSON array from DB, and I want it to manipulate. Currently it has discreet 8 elements, I want the array to manipulate it to get 2 elements, rest elements will be nested. My current JSON has this structure:
{
"itemId": 1,
"desc": [{
"type": "A",
"size": "xx",
"count": 12,
"price": 122
},
{
"type": "A",
"size": "xl",
"count": 18,
"price": 180
},
{
"type": "B",
"size": "xx",
"count": 12,
"price": 122
},
{
"type": "B",
"size": "xl",
"count": 12,
"price": 122
}]
}
I want the data to be manipulated to come like this:
{
"type": "A",
"desc":{
"size": "xx",
"count": 12,
"price": 122
},
{
"size": "xl",
"count": 12,
"price": 122
},
},
{
"type": "B",
"desc":{
"size": "xx",
"count": 12,
"price": 122
},
{
"size": "xl",
"count": 12,
"price": 122
},
}
I am using for each loop, but this is creating individual elements, i want just two elements in the resulting array.
Any solution will be appreciated.

You could try something like this:
var new_data = {
A: {type: 'A', desc: []},
B: {type: 'B', desc: []}
};
$.each(data.desc, function( index, value ) {
new_data[value.type].desc.push(value);
});
https://jsfiddle.net/5cnaxn04/
If you don't know the types you will get, you can build the object dynamically:
var new_data = {};
$.each(data.desc, function( index, value ) {
if(typeof new_data[value.type] === "undefined") {
new_data[value.type] = {type: value.type, desc: [value]}
} else {
new_data[value.type].desc.push(value);
}
});
https://jsfiddle.net/5cnaxn04/1/

You have some syntax errors in your code, as you are using {} for both Arrays and Objects, so I'd guess from the context. You need a few loops to make the data look exactly to what you want.
See JSFiddle.

Related

How to create a json object from two arrays in JavaScript

I have the following arrays
['a','b','c','d','e','f']
[1762, 770, 93, 474, 323, 351]
I would like to convert them into a list of json objects so that I end up with an object that looks a bit like this
{
"SomeObject": [
{
"name": "a",
"value": 1762
},
{
"name": "b",
"value": 770
},
{
"name": "c",
"value": 93
},
{
"name": "d",
"value": 474
},
{
"name": "e",
"value": 323
},
{
"name": "f",
"value": 351
}
]
}
How can I concert these arrays to the above object in JavaScript.
Thank you in advance
const keys = ['a','b','c','d','e','f'];
const values = [1762, 770, 93, 474, 323, 351];
const result = keys.map((key, i) => ({ name: key, value: values[i] }));
console.log(result);

JSON convert with Javascript [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 years ago.
Improve this question
I have a json file like as below
[{
"id": 2,
"name": "Ali",
"records":[{
"type": "L",
"total": 123
}, {
"type": "P",
"total": 102
}]
},{
"id": 3,
"name": "Mete",
"records":[{
"type": "O",
"total": 100
}, {
"type": "T",
"total": 88
}]
}]
I want to convert to like this
[{
"id": 2,
"name": "Ali",
record: {
"type": "L",
"total": 123
}
},{
"id": 2,
"name": "Ali",
record: {
"type": "P",
"total": 102
}
},{
"id": 3,
"name": "Mete",
record: {
"type": "O",
"total": 100
}
},{
"id": 3,
"name": "Mete",
record: {
"type": "T",
"total": 88
}
}]
how can i do it using javascript?
Here is what you could do. However, this doesn't work in IE as is as Object.assign that is being used, isn't yet supported in IE. However, it could be replaced with any javascript object clone methods.
You could check : What is the most efficient way to deep clone an object in JavaScript?
var input = [{
"id": 2,
"name": "Ali",
"records": [{
"type": "L",
"total": 123
}, {
"type": "P",
"total": 102
}]
}, {
"id": 3,
"name": "Mete",
"records": [{
"type": "O",
"total": 100
}, {
"type": "T",
"total": 88
}]
}];
var output = [];
input.forEach((obj) => {
var records = obj.records;
delete obj.records;
records.forEach((record) => {
// Doesnt have any support in IE.
var newRecord = Object.assign({}, obj);
newRecord.record = record;
output.push(newRecord);
});
});
console.log(output);
If you are fine to use jQuery, here is what you could do.
var input = [{
"id": 2,
"name": "Ali",
"records": [{
"type": "L",
"total": 123
}, {
"type": "P",
"total": 102
}]
}, {
"id": 3,
"name": "Mete",
"records": [{
"type": "O",
"total": 100
}, {
"type": "T",
"total": 88
}]
}];
var output = [];
input.forEach((obj) => {
var records = obj.records;
delete obj.records;
records.forEach((record) => {
var newRecord = jQuery.extend({}, obj);
newRecord.record = record;
output.push(newRecord);
});
});
console.log(output);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
Here's a functional (but probably not very efficient) way of doing it:
function transform(data) {
// Merge the sub arrays together
return [].concat.apply([], (data.map(person => {
// Return an array of copied objects for each person
return person.records.map(record => {
// For each record, copy the person information
return {
id: person.id,
name: person.name,
record: record
};
});
})));
}
console.log(transform([{
"id": 2,
"name": "Ali",
"records":[{
"type": "L",
"total": 123
}, {
"type": "P",
"total": 102
}]
},{
"id": 3,
"name": "Mete",
"records":[{
"type": "O",
"total": 100
}, {
"type": "T",
"total": 88
}]
}]));
There's a few ways but Array.prototype.map seems to fit the bill. This blurb should get you started:
// We'll assume your original array is called myArray
var newArray = myArray.map ( function ( d ) {
return {
id : (d.id || 'theIDYouWant'),
name : (d.name || 'theNameYouWant' ),
record : { type : d.type, total : d.total }
}
} );
var jsonStr = JSON.stringify ( newArray );
console.log ( jsonStr ); // should write out your JSON as expected.
This will do it and save what you want in new_json
try running the code snippet below
json = [{
"id": 2,
"name": "Ali",
"records": [{
"type": "L",
"total": 123
}, {
"type": "P",
"total": 102
}]
}, {
"id": 3,
"name": "Mete",
"records": [{
"type": "O",
"total": 100
}, {
"type": "T",
"total": 88
}]
}]
new_json = [];
for (var i = 0; i < json.length; i++) {
for (j = 0; j < json[i]['records'].length; j++) {
new_json.push({
id: json[i]['id'],
name: json[i]['name'],
record: json[i]['records'][j]
})
}
}
console.log(new_json);

Edit JSON data structure using JS

The original JSON file:
{
"data": {
"count_at_hub": [
{
"hub": "A",
"date": "",
"size": "1",
"count": 141
},
{
"hub": "A",
"date": "",
"size": "2",
"count": 44
},
{
"hub": "A",
"date": "",
"size": "3",
"count": 3
},
{
"hub": "A",
"date": "",
"size": "0",
"count": 1446
},
{
"hub": "B",
"date": "",
"size": "1",
"count": 202
},
{
"hub": "B",
"date": "",
"size": "0",
"count": 2082
},
{
"hub": "B",
"date": "",
"size": "3",
"count": 11
},
{
"hub": "B",
"date": "",
"size": "2",
"count": 53
}
],
"Part B":[
{
}
]
},
"success": true,
"errors": [],
"e": {}}
I want to change the structure to:
{
"data": {
"count_at_hub": [
{
"hub": "A",
"date": "",
"size1": 141,
"size2": 44,
"size3": 3,
"size4": 1446
},
{
"hub": "B",
"date": "",
"size1": 202,
"size2": 2082,
"size3": 11,
"count": 53
}
],
"Part B":[
{
}
]
},
"success": true,
"errors": [],
"e": {}}
Basically, I want to put all the count of the same hub under the same array. How do I come about doing this?
In terms of huge amount of data, will changing the JSON to the new file make the loading speed longer as compared to making JS looping through the original file to build a dashboard?
You can iterate and take an object as reference to the result array.
The elements of size": "0" go to size4.
var object = { "data": { "count_at_hub": [{ "hub": "A", "date": "", "size": "1", "count": 141 }, { "hub": "A", "date": "", "size": "2", "count": 44 }, { "hub": "A", "date": "", "size": "3", "count": 3 }, { "hub": "A", "date": "", "size": "0", "count": 1446 }, { "hub": "B", "date": "", "size": "1", "count": 202 }, { "hub": "B", "date": "", "size": "0", "count": 2082 }, { "hub": "B", "date": "", "size": "3", "count": 11 }, { "hub": "B", "date": "", "size": "2", "count": 53 }], "Part B": [{}] }, "success": true, "errors": [], "e": {} },
temp = [];
object.data.count_at_hub.forEach(function (a) {
if (!this[a.hub]) {
this[a.hub] = { hub: a.hub, date: a.date, size1: 0, size2: 0, size3: 0, size4: 0 };
temp.push(this[a.hub]);
}
this[a.hub]['size' + (+a.size || 4)] += a.count;
}, Object.create(null));
object.data.count_at_hub = temp;
console.log(object);
Hi this is my answer according to my proposal with sizes array in which each size.count is located at the index corresponding to the size value. i.e. size: 0 count : 2082 is placed like [2082,,,] in the array. To access the size and count you can do like count = sizes[size] The code is as follows;
var cag = [
{
"hub": "A",
"date": "",
"size": "1",
"count": 141
},
{
"hub": "A",
"date": "",
"size": "2",
"count": 44
},
{
"hub": "A",
"date": "",
"size": "3",
"count": 3
},
{
"hub": "A",
"date": "",
"size": "0",
"count": 1446
},
{
"hub": "B",
"date": "",
"size": "1",
"count": 202
},
{
"hub": "B",
"date": "",
"size": "0",
"count": 2082
},
{
"hub": "B",
"date": "",
"size": "3",
"count": 11
},
{
"hub": "B",
"date": "",
"size": "2",
"count": 53
}
],
reduced = cag.reduce((p,c) => (p[c.hub] ? p[c.hub].sizes[c.size] = c.count
: p[c.hub] = { "hub": c.hub,
"date": c.date,
"sizes": (new Array(c.size*1)).concat(c.count)},
p),{}),
result = Object.keys(reduced).map(k => reduced[k]);
console.log(result);
I first construct a reduced object which can also be used for your purposes but then i map this object into an array so that the data is in the array of objects form. You can use whichever form of data you like the best.
The slightly confusing part might be the (new Array(c.size*1)).concat(c.count) instruction. There we are creating a new object (through object literal) and we have to initiate a sparse sizes array with only one value inserted at the index position designated by the size value. So we construct a new Array of size (new Array(c.size*1)) however our c.size value is of string type. If we do like new Array("2") then we will receive an array with one string item ("2") at index 0. But we want an array in the size of 2. That's why we convert string "2" to number 2 by "2"*1 operation (multiplication operator type coerces string into number). So we receive an empty array of size 2. Now comes the concat operation which attaches our size value to the correct index location in the resulting array.
It's essentially the unification of the following two instructions
var sizes = [];
sizes[c.size] = c.count;

Merge two objects when there's a new key

I have two objects with the following structure and tried to merge them together.
I tried it with $.merge but its not the expected result.
Object 1 - Has not all attributes
{
"id": 23,
"name": "Article",
"related": 15 "items": [{
"name": "Test1",
"items": [{
"name": "Test2",
"items": [{
"name": "Test3",
"items": [{
"name": "Test4",
"items": [{
"name": "Test5",
"items": [{
"name": "Test6",
}]
}]
}]
}]
}]
}]
}, {
"id": 24…
}
Object 2 - with additional attributes
{
"id": 23,
"name": "Article",
"related": 15 "items": [{
"name": "Test1",
"id": 34 "items": [{
"name": "Test2",
"id": 57 "items": [{
"name": "Test3",
"id": 92 "items": [{
"name": "THIS ONE IS NOT EXISTING IN OBJECT 1 AND SHOULD NOT GET MERGED",
"id": 789
}, {
"name": "Test4",
"id": 12 "items": [{
"name": "Test5",
"id": 321 "items": [{
"name": "Test6",
"id": 285
}]
}]
}]
}]
}]
}]
}, {
"id": 24…
}
Does anyone know some smart trick? Is jQuery even necessary?
jQuery's $.extend will do what you want.
//merging two objects into new object
var new_object = $.extend(true, {}, object1, object2);
//merge object2 into object1
$.extend(true, object1, object2);
The 1st parameter: deep:true, see: https://api.jquery.com/jquery.extend/
Without jquery: https://jsfiddle.net/sLhcbewh/
function mymerge_sub(object1, object2)
{
for(var i in object2) {
if(i == 'items')
continue;
console.log(i);
if(object1[i] === undefined) {
console.log(i + ' not found');
object1[i] = object2[i];
}
}
if(object1.items !== undefined) {
mymerge_sub(object1.items[0], object2.items[0])
}
}
function mymerge(object1, object2) {
var ret = JSON.parse(JSON.stringify(object1));
mymerge_sub(ret, object2); // save obj 1
return ret;
}
var obj3 = mymerge(obj1, obj2);
If you want several items, you have to loop mymerge_sub(object1.items[j]... ).

mongodb getting the oldest of animals map/reduce

I've never tried map/reduce.
How would I get the oldest of each type of animal?
My data is like this:
[
{
"cateory": "animal",
"type": "cat",
"age": 4,
"id": "a"
},
{
"cateory": "animal",
"type": "bird",
"age": 3,
"id": "b"
},
{
"cateory": "animal",
"type": "cat",
"age": 7
"id": "c"
},
{
"cateory": "animal",
"type": "bird",
"age": 4,
"id": "d"
},
{
"cateory": "animal",
"type": "cat",
"age": 8,
"id": "e"
},
{
"cateory": "company",
"type": "Internet",
"age": 5,
"id": "Facebook"
}
]
I'm using node-mongodb-native. Thanks!
Your map function should look something like this:
map = function() {
emit({type: this.type}, {age: this.age});
}
And the reduce function:
reduce = function(key, values) {
maxAge = 0;
values.forEach(function(v) {
if (maxAge < v['age']) {
maxAge = v['age'];
}
});
return {age: maxAge};
}
It's pretty simple:
collection.find({type : 'animal'}).sort({animal: -1}).limit(1);

Categories