How to convert from a JSON array to a JSON object - javascript

I have this JSON that I'm getting back from a web service call:
{
"name": "My Name",
"path": "my path",
"id": "44",
"type": "my type",
"classes": "my classes"
},
{
"name": "his Name",
"path": "his path",
"id": "76",
"type": "his type",
"classes": "his classes"
}
I then need to convert it to this format
{
"44" : { "name" : "My Name", "path" : "my path" },
"76" : { "name" : "his Name", "path" : "his path" }
}
My initial naive attempt was this:
var myData = [];
for (var i = 0; i < rawData.length; i++) {
myData.push({
rawData[i].id :
{
"path": rawData[i].path,
"name": rawData[i].name
}
});
which fails with syntax errors, so I eventually got to this:
var myData = [];
for (var i = 0; i < rawData.length; i++) {
myData.push(rawData[i].id,
{
"path": rawData[i].path,
"name": rawData[i].name
});
and it mostly works. My array is populated, but the problem is that my myData array doesn't have the "44", and "76" part of the object, just the { "name" : "", "path" : "" } part. I expect this is due to a lack of understanding on my part of how JSON and javscript objects work.

Your desired output isn't an array, so that's your starting point. The output you've said you want is an object, not an array.
You build your result by creating a blank object and then adding the objects to it using id as the key:
var myData = {};
rawData.forEach(function(entry) {
myData[entry.id] = {
name: entry.name,
path: entry.path
};
});
Or if you don't want to use forEach (it's ES5, but can be shimmed for older browsers), the old-fashioned way:
var myData = {};
var index, entry;
for (index = 0; index < rawData.length; ++index) {
entry = rawData[index];
myData[entry.id] = {
name: entry.name,
path: entry.path
};
}

Don't use Array.prototype.push(), use the square bracket notation and define your output as an object not an array.
var myData = {};
for (var i = 0; i < rawData.length; i++) {
myData[rawData[i].id] = {
"path": rawData[i].path,
"name": rawData[i].name
}
}

You need to convert your id to a string?
var myData = {};
for (var i = 0; i < rawData.length; i++) {
myData[String(rawData[i].id)] = {
"path": rawData[i].path,
"name": rawData[i].name
};
}

A variation on what other posters have written:
// Create a new empty object.
var out = {};
// Loop over your array of objects
// Add the each object id as a key to the output object, and the object as the value.
for (var i = 0, l = arr.length; i <l; i++) {
var obj = arr[i];
out[obj.id] = obj;
// Delete the properties from the newly added object you don't want.
delete obj.id;
delete obj.type;
delete obj.classes;
}

Related

Javascript .getJSON multiple URLs

I have WEbDataconnector in Javascript, which download data from .json file and load table:
myConnector.getData = function(table, doneCallback) {
$.getJSON("http://url/api/opls/number/tasks?apiKey", function(resp) {
var feat = resp.data,
tableData = [];
// Iterate over the JSON object
var keys = Object.keys(feat);
for (var i = 0, len = keys.length; i < len; i++) {
tableData.push({
"taskId": feat[keys[i]].taskId,
"owner": feat[keys[i]].owner,
"description": feat[keys[i]].description,
"responsible": feat[keys[i]].responsible,
});
}
table.appendRows(tableData);
doneCallback();
});
My problem is that i have multiple URL, with different numbers and apikeys. And i need combine data from all URLs into one table.
Could anyone please help me out? Thank you.
edit:
If i add more elements to data.push() method it ends with:"null is not an object" because some objects in JSON are null,
example of JSON:
"1026533": {
"taskId": 1026533,
"opl": 6919,
"owner": "name",
"description": "text",
"responsible": "name",
"taskStart": {
"date": "2016-03-21 13:28:11.000000",
"timezone_type": 3,
"timezone": "Europe\/Prague"
but sometimes there is an element taskStart with null:
"1026535": {
"taskId": 1026535,
"opl": 6919,
"owner": "name",
"description": "text",
"responsible": "name",
"taskStart": null,
how can i check this and push all data or null? thank you
Use recursion and named function expression with a list of URL.
myConnector.getData = function (table, doneCallback) {
var urls = [ /* the urls */]
if (urls.length == 0) return doneCallback();
$.getJSON(urls.shift(), function callback(resp) {
var feat = resp.data,
tableData = [];
// Iterate over the JSON object
var keys = Object.keys(feat);
for (var i = 0, len = keys.length; i < len; i++) {
tableData.push({
"taskId": feat[keys[i]].taskId,
"owner": feat[keys[i]].owner,
"description": feat[keys[i]].description,
"responsible": feat[keys[i]].responsible,
});
}
table.appendRows(tableData);
var url = urls.shift();
if (url) return $.getJSON(url, callback); // recursion happens here
doneCallback();
});
}
Keep an array containing all the urls that you need to fetchs.
urls = [
'http://url/api/opls/number1/tasks?apiKey1',
'http://url/api/opls/number2/tasks?apiKey2',
'http://url/api/opls/number3/tasks?apiKey3'
];
Then iterate over the array and send an ajax request on each url.
urls.forEach(function(url) {
$.getJSON(url, function(resp) {
var feat = resp.data,
let data = [];
// Iterate over the JSON object
var keys = Object.keys(feat);
for (var i = 0, len = keys.length; i < len; i++) {
data.push({
"taskId": feat[keys[i]].taskId,
"owner": feat[keys[i]].owner,
"description": feat[keys[i]].description,
"responsible": feat[keys[i]].responsible,
});
}
table.appendRows(data);
doneCallback();
});
});

reading json from file in javascript

I have this json file:
test.json:
{"rows" : [
{"key": "value"},
{"key": "value"}
]
}
I tried this code to read it:
var json = require('test.json');
for (var row in json.rows) {
console.log(row.key);
}
it prints:
/usr/local/bin/node json-parser.js
undefined
undefined
What am I doing wrong?
Where row is the variable holding property name not the object, so you need to retrieve it using the property name ( Refer : for...in loop documentation). In your case it will be the index of array. There is no need to use for...in iterator here, a simple for loop is enough.
for (var row in json.rows) {
console.log(json.rows[row].key);
}
var json = {
"rows": [{
"key": "value"
}, {
"key": "value"
}]
};
for (var row in json.rows) {
console.log(json.rows[row].key);
}
With a simple for loop
for (var i=0;i < json.rows.length; i++) {
console.log(json.rows[i].key);
}
var json = {
"rows": [{
"key": "value"
}, {
"key": "value"
}]
};
for (var i = 0; i < json.rows.length; i++) {
console.log(json.rows[i].key);
}
Since the property holds an array useArray#forEach method to iterate.
json.rows.forEach(function(v){
console.log(v.key);
}
var json = {
"rows": [{
"key": "value"
}, {
"key": "value"
}]
};
json.rows.forEach(function(v) {
console.log(v.key);
})

JSON.parse(data) return [undefine]

data = {
"users": [
[{
"value": "01",
"text": "ABC XYZ"
}],
[{
"value": "02",
"text": "XYZ ABC"
}]
]
}
var jsonData = JSON.parse(data);
for (var i = 0; i < jsonData.users.length; i++) {
var userlist = jsonData.users[i];
alert(userlist.text)
}
This output: [undefine];
But i want to get [ABC XYZ] and [XYZ ABC].
So how can I get text or value from this array?
data is already a JavaScript object, so no need for the extra JSON.parse.
You are getting an undefined result because users is an array of arrays, rather than an array of objects.
Try accessing the userlist like this:
var userlist = data.users[0][i];
JSBin: https://jsbin.com/sifoyivayi/edit?html,js,output
Your object contains nested array. Try like following.
var data = { "users": [[{ "value": "01", "text": "ABC XYZ" }], [{ "value": "02", "text": "XYZ ABC" }]] };
for (var i = 0; i < data.users.length; i++) {
var userlist = data.users[i][0];
alert(userlist.text);
}
Try like this:
var data={"users":[[{"value":"01","text":"ABC XYZ"}],[{"value":"02","text":"XYZ ABC"}]]};
for (var i = 0; i < data.users.length; i++) {
var userlist = data.users[0][i];
alert(userlist.text);
}

JSON Data Fuzzy merge

I have a JSON data like this
{
"array": {
"InvestmentsDeposits": {
"NAME": "Investments & Deposits",
"PARENT": [
{
"CONTENT_ID": "Promotions",
"DISPLAY_ORDER": 3,
"PATH": "/Promotions"
}
]
},
"InvestmentsDeposits$$$d": {
"NAME": "Deposits",
"PARENT": [
{
"CONTENT_ID": "NewPromotion",
"text" : "newtext"
}
]
}
}
}
I need to search for fuzzy data and merge. For example InvestmentsDeposits and InvestmentsDeposits$$$d need to be merged because it matches closely in name
Need to use javascript for this
For now I can make sure source data will always have $$$d at the end to merge with the target data without $$$d i.e., InvestmentDeposits.
My final merged content should be like this
{
"array": {
"InvestmentsDeposits": {
"NAME": "Deposits",
"PARENT": [
{
"CONTENT_ID": "NewPromotion",
"DISPLAY_ORDER": 3,
"PATH": "/Promotions"
"text": "newtext"
}
]
}
}
}
any help on this one?
What I have tried so far
var json0 = {
"InvestmentsDeposits": {
"NAME": "Investments & Deposits",
"PARENT": [
{
"CONTENT_ID": "Promotions",
"DISPLAY_ORDER": 3,
"PATH": "/Promotions"
}
]
}
};
var json1 =
{
"InvestmentsDeposits$$$d": {
"NAME": "Deposits",
"PARENT": [
{
"CONTENT_ID": "NewPromotion",
"text" : "newtext"
}
]
}
};
// Merge object2 into object1, recursively
$.extend( true, json0, json1 );
I am able to merge the data if i am able to split the InvestmentDeposits and InvestmentDeposits$$$d in to two distinct JSON objects but how to split and move the $$$d data in to another object? to make the jquery extend work
Use Object.keys() to find an object's keys and figure out what data to move over. You can compare the first key with the others to find matches, then remove the keys you just looked at until all of them are gone. Here's an example with a similar object.
var dat = {
"InvestmentsDeposits": {
"NAME": "Investments & Deposits",
"CONTENT_ID": "Promotions",
"DISPLAY_ORDER": 3,
"PATH": "/Promotions"
}, "InvestmentsDeposits$$$d": {
"NAME": "Deposits",
"CONTENT_ID": "NewPromotion",
"text" : "newtext"
},
"NotLikeTheOthers": {
"Um": "Yeah."
}
};
var result = {}; // This will be the merged object
var keys = Object.keys(dat); // Contains keys
while(keys.length) {
var i=1;
for(; i<keys.length; i++) { // Find matches
if(keys[0] == keys[i] + '$$$d') { // Match type 1
result[keys[i]] = dat[keys[i]]; // Copy orig
for(var j in dat[keys[0]]) { // Replace values
result[keys[i]][j] = dat[keys[0]][j];
}
keys.splice(i,1);
keys.shift();
i = 0;
break;
} else if(keys[i] == keys[0] + '$$$d') { // Reverse matched
result[keys[0]] = dat[keys[0]];
for(var j in dat[keys[i]]) {
result[keys[0]][j] = dat[keys[i]][j];
}
keys.splice(i,1);
keys.shift();
i = 0;
break;
}
}
if(i > 0) { // Didn't find a match
result[keys[0]] = dat[keys[0]];
keys.shift();
}
}
alert(JSON.stringify(result));
Note that Object.keys() requires IE9+.

How apply ko.utils.arrayGetDistinctValues on two dimensional arrays

I have an ko.observableArray with two dimensions, i.e. "id" and "name".
Id will always be distinct, but name can hold the same value.
self.myArray = ko.observableArray( [
{ "id": "1", "name": "Barbara" }, 
{ "id": "2", "name": "Edwin" }, 
{ "id": "3", "name": "Barbara" } 
] );
However I want to filter the array so that my result holds only the first occurrence of "name".
The result I want is:
self. myFilteredArray = [
{ "id": "1", "name": "Barbara" }, 
{ "id": "2", "name": "Edwin" } 
];
I have been trying to figure this out using ko.utils.arrayGetDistinctValues(), but how can I utilize it on solely one chosen dimension?
You could use a computed for this:
viewModel.myFilteredArray = ko.computed(function() {
var rv = [], names = [];
for(var i=0; i<this.myArray().length; i++) {
if(names.indexOf(this.myArray()[i].name) === -1) {
rv.push(this.myArray()[i]);
names.push(this.myArray()[i].name);
}
}
return rv;
}, viewModel);
I can suggest a function, that loops through the array, builds map of property values for each item and checks, whether the current value was already added. Something like this:
function filterByFirstOccurance(arr, prop) {
var propValuesHash = {},
result = [];
for (var i = 0, l = arr.length; i < l; i++) {
var item = arr[i],
propValue = item[prop];
if (item.hasOwnProperty(prop) && !propValuesHash[propValue]) {
propValuesHash[propValue] = true;
result.push(item);
}
}
return result;
};
Fiddle

Categories

Resources