I am trying to convert a JSON string in a Javascript object literal. I think it is possible with some loops, but i couldn't get it done. The target structure is shown below, "chartData".
Fiddle can be found here: http://jsbin.com/ajemih/13/edit
Here's the JSON data:
{
"1b":{
"allLoad":"130",
"loadMovement":"111",
"allMovement":"111"
},
"1a":{
"allLoad":"910",
"loadMovement":"671",
"allMovement":"280"
},
"systemLoad":"963"
}
This should it look like after the conversion:
chartData = [[['loadMovement', 111],
['allMovement', 120],
['allLoad', 130]],
[['Load+Move', 671],
['allMovement', 280],
['allLoad', 910]]];
I think this would work:
Working demo: http://jsfiddle.net/jfriend00/YmjDR/
var data = {
"1b":{
"allLoad":"130",
"loadMovement":"111",
"allMovement":"111"
},
"1a":{
"allLoad":"910",
"loadMovement":"671",
"allMovement":"280"
},
"systemLoad":"963"
};
var chartData = [];
for (var i in data) {
var item = data[i];
var outer = [];
// skip over items in the outer object that aren't nested objects themselves
if (typeof item === "object") {
for (var j in item) {
var temp = [];
temp.push(j);
temp.push(item[j]);
outer.push(temp);
}
}
if (outer.length) {
chartData.push(outer);
}
}
You could do something like this:
var chartData = []
for(var key in data) {
var properties = data[key];
if(typeof properties === "object") {
var array = [];
for(var propKey in properties) {
array.push([propKey, properties[propKey]])
}
chartData.push(array);
}
}
Check out the fiddle.
You need to map the data manually. Thats actually more a diligent but routine piece of work.
var jsonData = 'your json string';
Object.keys( jsonData ).map(function( key ) {
if( typeof jsonData[ key ] === 'object' ) {
return Object.keys( jsonData[ key ] ).sort(function( a, b ) {
return +jsonData[ key ][ a ] - +jsonData[ key ][ b ];
}).map(function( name ) {
return [ name, jsonData[ key ][ name ] ];
});
}
}).filter( Boolean );
The above code will sort each group by its numeric value and then map a new array in the required style. Since .map() possibly returns undefined values on non-object elements, we need to filter those out before or afterwards.
See http://jsfiddle.net/WjZB2/2/
I had similar problem.
My goal was to convert a list of strings into a valid format for http://ivantage.github.io/angular-ivh-treeview/
This was my starting point:
[
"A\\A1\\Test1",
"A\\A1\\Test2",
"A\\A2\\Test3",
"B\\Test4",
"B\\Test5",
"B\\B1\\Test6",
"B\\B1\\Test7",
"B\\B1\\Test8",
"C\\C1\\C1a\\Test9",
"C\\C1\\C1b\\Test10",
"C\\C2\\C2a\\Test11",
"C\\C2\\C2a\\Test12",
"C\\C2\\C2a\\Test13",
"C\\C3\\Test14",
"C\\Test15",
"C\\Test16"
]
And I needed following format:
[
{
"label": "Selected Tests",
"children": [
{
"label": "A",
"children": [
{
"label": "A1",
"children": [
{
"label": "Test1",
"value": true
},
{
"label": "Test2",
"value": true
}
]
},
{
"label": "A2",
"children": [
{
"label": "Test3",
"value": true
}
]
}
]
}
]
}
]
See my solution https://jsfiddle.net/ydt3gewn/
Related
My JSON output is similar to this below object and we have an array values as showing below
const object1 = {
"sublists": {
"item": [{
"line": "1",
"amount": "1200.00",
"id": "227",
"item": "227",
"item_display": "5800520002800",
"quantity": "1"
}
],
"shipping": [{
"line": "1",
"amount": "1200.00",
"id": "227",
"quantity": "1"
}
]
}
}
I am trying to get the name of arrays and values in separate variable as showing below
Array name :item, line: , 1
Array name :item , amount : 1200
Array name :item, id : 227
and so on ...
the array properties can varry depending on the json ouput , im looking for a dynamic script in which i could access the array name and properties
Can someone help me on this ?
try this
function iterateObject(obj, parent) {
if (typeof obj == "object")
if (!Array.isArray(obj))
Object.keys(obj).forEach((prop) => {
if (typeof obj[prop] == "object") iterateObject(obj[prop], prop);
else console.log(`Parent name : ${parent}, ${prop} : ${obj[prop]}`);
});
else
obj.forEach((elem) => {
iterateObject(elem, parent);
});
else console.log(`Parent name : ${parent}, ${parent} : ${obj}`);
}
iterateObject(object1,"sublists");
UPDATE
this is code for your json in comment
iterateObject(object01,"item");
The easy way to achieve the desired outcome is to pass the 'parentKey' to the recursive call:
const object1 = {sublists: {sales_order: [], data: [{"key1": "a", "value": 2 }, {"key1": "b", "value": 4 }], memo: [{"key1": "a", "value": 5 }] } };
function printValues(obj, parentName = null) {
if (Object.prototype.toString.call(obj) === '[object Array]') {
obj.forEach(o => console.log(`Array name: ${parentName}. Key1: ${o.key1}. Value: ${o.value}`));
} else {
for (let k in obj) {
printValues(obj[k], k);
}
}
};
printValues(object1) ;
The first if statement if to check if the varaible is an array or object. Logic taken from:
How do you check if a variable is an array in JavaScript?
Array name: data. Key1: a. Value: 2
Array name: data. Key1: b. Value: 4
Array name: memo. Key1: a. Value: 5
I believe this will solve your problem. I followed the recursive nature of the code you gave and adapted it to make sure it was giving the output you desired. If you have any questions please let me know, and I'll try to address them.
function printValues(obj) {
for (const [objKey, objValue] of Object.entries(
obj
)) {
if (
typeof objValue === 'object' &&
!objValue.length
) {
printValues(objValue);
} else if (
objValue !== undefined &&
objValue.length > 0
) {
for (let i = 0; i < objValue.length; i++) {
const currentObject = objValue[i];
let str = '';
for (const [key, value] of Object.entries(
currentObject
)) {
str += `Array name: ${objKey} , key1: ${key} , value: ${value}\n`;
}
console.log(str);
}
}
}
}
Base Object :
obj = {
"place": "{{base_gplaceId}}",
"feedInputs": [
{
"subCategoryQuestion": "{{base_gquestionId}}",
"context": "other",
"image": "abc.jpg",
"mediaMetadata": {
"stickerList": [
{
"id": "someid2",
"sticker": "delish",
"weight": 3
}
],
"textList": [
{
"text": "What an evening!!!"
}
]
}
}
]
};
more keys can have more nesting,
want to set the values of keys = "", one by one and push the updated object to an array
Expected OP :
[
{"place":"","feedInputs":[{"subCategoryQuestion":"{{base_gquestionId}}","context":"other","image":"abc.jpg","mediaMetadata":{"stickerList":[{"id":"someid2","sticker":"delish","weight":3}],"textList":[{"text":"Whatanevening!!!"}]}}]},
{"place":"{{base_gplaceId}}","feedInputs":[{"subCategoryQuestion":"","context":"other","image":"abc.jpg","mediaMetadata":{"stickerList":[{"id":"someid2","sticker":"delish","weight":3}],"textList":[{"text":"Whatanevening!!!"}]}}]},
{"place":"{{base_gplaceId}}","feedInputs":[{"subCategoryQuestion":"{{base_gquestionId}}","context":"","image":"abc.jpg","mediaMetadata":{"stickerList":[{"id":"someid2","sticker":"delish","weight":3}],"textList":[{"text":"Whatanevening!!!"}]}}]},
{"place":"{{base_gplaceId}}","feedInputs":[{"subCategoryQuestion":"{{base_gquestionId}}","context":"other","image":"","mediaMetadata":{"stickerList":[{"id":"someid2","sticker":"delish","weight":3}],"textList":[{"text":"Whatanevening!!!"}]}}]},
{"place":"{{base_gplaceId}}","feedInputs":[{"subCategoryQuestion":"{{base_gquestionId}}","context":"other","image":"abc.jpg","mediaMetadata":{"stickerList":[{"id":"","sticker":"delish","weight":3}],"textList":[{"text":"Whatanevening!!!"}]}}]}
,...........]
tried couple of recursions, but not able to break after update inside the nested objects,
any simplistic approach ?
You could iterate the properties and change the values who are not objects. For having access to the complete object store the root as well and take a copy of the object with stringify and parse for the result set.
function visitAll(object, root = object) {
return Object
.keys(object)
.flatMap(k => {
if (object[k] && typeof object[k] === 'object') return visitAll(object[k], root);
const value = object[k];
object[k] = '';
const result = JSON.parse(JSON.stringify(root));
object[k] = value;
return result;
});
}
var object = { place: "{{base_gplaceId}}", feedInputs: [{ subCategoryQuestion: "{{base_gquestionId}}", context: "other", image: "abc.jpg", mediaMetadata: { stickerList: [{ id: "someid2", sticker: "delish", weight: 3 }], textList: [{ text: "What an evening!!!" }] } }] },
result = visitAll(object);
result.forEach(o => console.log(JSON.stringify(o)));
.as-console-wrapper { max-height: 100% !important; top: 0; }
I have an array of objects:-
var arr1 = [{
"name": "A"
}, {
"name": "B"
}, {
"name": "C"
}, {
"name": "D"
}];
I want to add a new property to each element which are not present in the second array.
var arr2 = [C,D]
The resulted array should be:-
arr1 = [{
"name": "A",
"country":"USA"
}, {
"name": "B",
"country":"USA"
}, {
"name": "C"
}, {
"name": "D"
}];
Can any one tell me how to achieve that?
I want to add a new property to each element which are not present in the second array.
That completely changes the question you originally asked.
If the items are mutable, you'd just loop through the array adding the property to selected items. There are many ways to do that, such as forEach:
arr1.forEach(function(item) {
if (arr2.indexOf(item.name) === -1) {
item.country = "USA";
}
});
Live Example:
var arr1 = [{
"name": "A"
}, {
"name": "B"
}, {
"name": "C"
}, {
"name": "D"
}];
var arr2 = ["C", "D"];
arr1.forEach(function(item) {
if (arr2.indexOf(item.name) === -1) {
item.country = "USA";
}
});
console.log(arr1);
If they're immutable, you'd use map instead:
arr1 = arr1.map(function(item) {
if (arr2.indexOf(item.name) === -1) {
return /*...create item with `country = "USA"` here...*/;
} else {
return item;
}
});
Live Example:
var arr1 = [{
"name": "A"
}, {
"name": "B"
}, {
"name": "C"
}, {
"name": "D"
}];
var arr2 = ["C", "D"];
arr1 = arr1.map(function(item) {
if (arr2.indexOf(item.name) === -1) {
return {name: item.name, country: "USA"};
} else {
return item;
}
});
console.log(arr1);
Original answer: (to your original question)
You would loop over the resulting array adding the property. There are many ways to do that, such as forEach:
arr1.forEach(function(item) {
item.country = "USA";
});
Technically, you could make it a side-effect of your filter, like this:
var arr1 = arr1.filter(function(item){
if (arr2.indexOf(item.name) === -1) {
item.country = "USA";
return true;
};
return false;
});
BUT, side-effects in filter callbacks (and similar) are generally not a great idea. Unless you know that the resulting array (arr1) is hundreds of thousands of entries, the second pass keeps things simple by filtering and then modifying.
Use Array.forEach and add the property if the element is not present - by using the same comparison you were already using.
I am Having the Array of objects. Like this
var result=[{"batchId":123, "licenseId":2345ef34, "name":"xxx"},
{"batchId":345, "licenseId":2345sdf334, "name":"www"},
{"batchId":145, "licenseId":234sdf5666, "name":"eee"},
{"batchId":455, "licenseId":asfd236645 },
{"batchId":678, "name":"aaa"}]
i want to have the array which is contains all the three properties. the Output should be like this.
[{"batchId":123, "licenseId":2345ef34, "name":"xxx"},
{"batchId":345, "licenseId":2345sdf334, "name":"www"},
{"batchId":145, "licenseId":234sdf5666, "name":"eee"}]
can anybody Help me on this
This is simple with the array .filter() method:
var result=[
{"batchId":123, "licenseId":"2345ef34", "name":"xxx"},
{"batchId":345, "licenseId":"2345sdf334", "name":"www"},
{"batchId":145, "licenseId":"234sdf5666", "name":"eee"},
{"batchId":455, "licenseId":"asfd236645" },
{"batchId":678, "name":"aaa"}
];
var filtered = result.filter(function(v) {
return "batchId" in v && "licenseId" in v && "name" in v;
});
console.log(filtered);
The function you pass to .filter() is called for each element in the array. Each element for which you return a truthy value will be included in the resulting array.
In the code above I simply test if all three of those specific properties are present, although there are other tests you could use that would get the same result for that data:
var result=[ {"batchId":123, "licenseId":"2345ef34", "name":"xxx"}, {"batchId":345, "licenseId":"2345sdf334", "name":"www"}, {"batchId":145, "licenseId":"234sdf5666", "name":"eee"}, {"batchId":455, "licenseId":"asfd236645" }, {"batchId":678, "name":"aaa"} ];
var filtered = result.filter(function(v) {
return Object.keys(v).length === 3;
});
console.log(filtered);
Note that you need to put your licenseId values in quotes, because they seem to be string values.
var result = [{
"batchId": 123,
"licenseId": '2345ef34',
"name": "xxx"
}, {
"batchId": 345,
"licenseId": '2345sdf334',
"name": "www"
}, {
"batchId": 145,
"licenseId": '234sdf5666',
"name": "eee"
}, {
"batchId": 455,
"licenseId": 'asfd236645'
}, {
"batchId": 678,
"name": "aaa"
}];
function hasProperties(object) {
return object.hasOwnProperty('batchId') && object.hasOwnProperty('licenseId') && object.hasOwnProperty('name')
}
result.filter(e => hasProperties(e));
I would like to know what is the faster way to retrieve an object by its id, keeping in consideration that the structure where it is stored could be different.
Does any native function in JS for this operation?
Example 1
var source = {
"page": [{
"id": "1",
"site": "",
"items": [{
"id": "2"
}, {
"id": "3",
"anotherItem": [{
"id": "4"
}, {
"id": "5"
}]
}]
}, {
"id": "6"
}]
};
Example 2
Structure could be completely different, the script should be always able to get the object containing id.
{
"smtElse": {
"id": "1"
}
}
No, there is no native function.
The fastest way is the same as the only way which is to iterate over the object, probably recursively, looking for IDs and returning what you want.
I solved using the following script, as it seems no native functionality is available.
var data = {
item: [
{
itemNested: [
{
itemNested2: [{
id: "2"
}
]
}
]
}
]
};
function findById(obj, id) {
var result;
for (var p in obj) {
if (obj.id == id) {
return obj;
} else {
if (typeof obj[p] === 'object') {
result = findById(obj[p], id);
if (result) {
return result;
}
}
}
}
return result;
}
var result = findById(data, "2");
console.log(result);
you can try this
<script type="text/javascript">
var re = /"id":\s+"(.*?)"/;
var sourcestring = "source string to match with pattern";
var results = [];
var i = 0;
for (var matches = re.exec(sourcestring); matches != null; matches = re.exec(sourcestring)) {
results[i] = matches;
for (var j=0; j<matches.length; j++) {
alert("results["+i+"]["+j+"] = " + results[i][j]);
}
i++;
}