I have a dictionary where i want to extract some fields with their keys. So what i want is call a function where i pass this dictionary and the keys.
var posts = {
"code":"ok",
"data":[
{
"id":1,
"username":"example1",
"data":
{
"id":4,
"name":"fran"
},
},
{
"id":2,
"username":"example2",
"data":
{
"id":5,
"name":"manuel"
}
}
]
};
So I would like to have a new dictionary where i have the nested value as a simple dictionary value.
[{
"id":1,
"username":"example1",
"name":"fran"
},
"id":2,
"username":"example2",
"name":"manuel"
}}
function dict(obj)
{
var list = Object.assign({},obj).data;
list.forEach((e,i,a) => {
e.name = e.data.name;
delete e.data;
});
return list;
}
that's how you dictionary function should look
I have tried this one. I think i have problem because i am creating a dictionary when node is "name" in the iteration. So i want to confirm if it's OK or there is any another way to do this.
var list = [];
var dict = {};
function iterate(obj, stack) {
for (var property in obj) {
if (obj.hasOwnProperty(property)) {
if (typeof obj[property] == "object") {
iterate(obj[property], stack + '.' + property);
} else {
console.log(property + " " + obj[property]);
dict[property] = obj[property];
if(property=="name"){
list.push(dict);
dict ={};
}
}
}
}
return list;
}
var simplified = iterate(posts.data, '');
console.log(simplified);
Related
We assume the following json file
{
"id": "test",
"child" : [
{
"id": "alpha",
"child":[]
},
{
"id": "beta",
"child":[]
}
]
}
In JavaScript how can I insert a JSON object into a specific JSON array location using a query like flavor
I want to insert in the child where the neighbour id is alpha.
I don't want to use position
Thanks.
You could write a recursive function to insert an element at the specified index of your JSON object a like so:
const yourJSON = `
{
"id": "test",
"child" : [
{
"id": "alpha",
"child":[]
},
{
"id": "beta",
"child":[]
}
]
}
`;
function insertIntoChildJSON(sourceJSON, childId, childPosition, value) {
function insertIntoChild(data, childId, childPosition, value) {
if (data.id === childId) {
data.child[childPosition] = value;
} else {
if (data.child.length > 0) {
for (let i = 0; i < data.child.length; ++i) {
data.child[i] = insertIntoChild(
data.child[i],
childId,
childPosition,
value
);
}
}
}
return data;
}
const parsedSource = JSON.parse(sourceJSON);
return JSON.stringify(
insertIntoChild(parsedSource, childId, childPosition, value)
);
}
console.log(
insertIntoChildJSON(yourJSON, 'alpha', 1, { id: 'charlie', child: [] })
);
Let's assume file.json is your json string
import objects from './file.json'
For querying, you could come up with something like this.
function query(column, value) {
let children = objects.child
return children.find(child => child[column] === value)
}
For multiple returns (array), use filter instead
function query(column, value) {
let children = objects.child
return children.filter(child => child[column] === value)
}
Then inserting data would be:
function insert(column, value, insert) {
if (insert) {
let children = objects.child
let item = children.find(child => child[column] === value)
if (variable.constructor === Array) {
item.child.push(...insert)
} else {
item.child.push(insert)
}
}
}
This code works for converting the JSON to an object where each name object turns into the key for either its value, or if it instead has its own element object breaks that out and does the same to its contents.
Is there a better way to do this that would also allow for more extensiblity of the JSON schema?
Is there a way I can get it all down to a simpler function that I can pass the first element and have it convert it down to whatever depth the schema goes?
const fs = require('fs');
{
let scheme = JSON.parse('{"$schema":{"root":{"name":"THINGY","dtd":{"name":"DOCTYPE","value":"something.dtd","commentBefore":["?xml version='1.0'?","Version NULL"]},"ele":{"name":"REPORT","ele":[{"name":"SEGMENT0","ele":[{"name":"NUMBER1","value":""},{"name":"NUMBER2","value":""}]},{"name":"SEGMENT1","ele":[{"name":"RECORD1","ele":[{"name":"NUMBER1","value":""},{"name":"NUMBER2","value":""}]}]},{"name":"SEGMENT2","ele":[]},{"name":"SEGMENT3","ele":[]},{"name":"SEGMENT4","ele":[]},{"name":"SEGMENT5","ele":[]}]}}}}').$schema.root;
let depth = 0;
var compiled = {
[scheme.ele.name]: scheme.ele.ele.map(function(i) {
if (typeof i.ele != 'undefined') {
return {
[i.name]: i.ele.map(function(k) {
if (typeof k.ele != 'undefined') {
return {
[k.name]: k.ele.map(function(p) {
if (typeof p.ele != 'undefined') {
return {
[p.name]: p.ele
};
} else {
return {
[p.name]: p.value
};
}
})
};
} else {
return {
[k.name]: k.value
};
}
})
};
} else {
return {
[i.name]: i.value
};
}
})
};
}
console.log(JSON.stringify(compiled, 0, 2));
I should add, this is intended to eventually also apply validation and grab real data when it gets to the string objects.
The output looks like this:
{
"REPORT": [
{
"SEGMENT0": [
{
"NUMBER1": ""
},
{
"NUMBER2": ""
}
]
},
{
"SEGMENT1": [
{
"RECORD1": [
{
"NUMBER1": ""
},
{
"NUMBER2": ""
}
]
}
]
},
{
"SEGMENT2": []
},
{
"SEGMENT3": []
},
{
"SEGMENT4": []
},
{
"SEGMENT5": []
}
]
}
You could destructure the object, get name, ele and value and return a new object with name as key and either an array by mapping the objects of ele or the value.
const
getData = ({ name, ele, value }) => ({
[name]: Array.isArray(ele)
? ele.map(getData)
: value
});
var scheme = JSON.parse('{"$schema":{"root":{"name":"THINGY","dtd":{"name":"DOCTYPE","value":"something.dtd","commentBefore":["?xml version=\'1.0\'?","Version NULL"]},"ele":{"name":"REPORT","ele":[{"name":"SEGMENT0","ele":[{"name":"NUMBER1","value":""},{"name":"NUMBER2","value":""}]},{"name":"SEGMENT1","ele":[{"name":"RECORD1","ele":[{"name":"NUMBER1","value":""},{"name":"NUMBER2","value":""}]}]},{"name":"SEGMENT2","ele":[]},{"name":"SEGMENT3","ele":[]},{"name":"SEGMENT4","ele":[]},{"name":"SEGMENT5","ele":[]}]}}}}').$schema.root,
result = getData(scheme.ele);
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Nina's answer is cleaner but this looks a bit more like your code so I figured I'd post it anyway.
let scheme = JSON.parse('{"$schema":{"root":{"name":"THINGY","dtd":{"name":"DOCTYPE","value":"something.dtd","commentBefore":["?xml version=\'1.0 \'?","Version NULL"]},"ele":{"name":"REPORT","ele":[{"name":"SEGMENT0","ele":[{"name":"NUMBER1","value":""},{"name":"NUMBER2","value":"1"}]},{"name":"SEGMENT1","ele":[{"name":"RECORD1","ele":[{"name":"NUMBER1","value":"2"},{"name":"NUMBER2","value":""}]}]},{"name":"SEGMENT2","ele":[]},{"name":"SEGMENT3","ele":[]},{"name":"SEGMENT4","ele":[]},{"name":"SEGMENT5","ele":[]}]}}}}').$schema.root;
let newScheme = JSON.parse('{"$schema":{"root":{"name":"THINGY","dtd":{"name":"DOCTYPE","value":"something.dtd","commentBefore":["?xml version=\'1.0 \'?","Version NULL"]},"ele":{"name":"REPORT","ele":[{"name":"SEGMENT0","ele":[{"name":"NUMBER1","value":"1"},{"name":"NUMBER2","value":"3"}]},{"name":"SEGMENT1","ele":[{"name":"RECORD1","ele":[{"name":"NUMBER1","value":"4"},{"name":"NUMBER2","value":""}]}]},{"name":"SEGMENT2","ele":[]},{"name":"SEGMENT3","ele":[]},{"name":"SEGMENT4","ele":[]},{"name":"SEGMENT5","ele":[]}]}}}}').$schema.root;
//Yay, recursion!
function mapObj(a, o = {}) {
let array = o[a.name] || [];
for (let i = 0; i < a.ele.length; i++) {
let b = a.ele[i];
array[i] = b.ele ?
mapObj(b, array[i]) : {
[b.name]: b.value
};
}
o[a.name] = array;
return o;
}
let obj = mapObj(scheme.ele);
console.log(obj);
console.log(mapObj(newScheme.ele, obj));
I'm trying to get the value of "id" of the below mentioned array of json but i'm not able to get the result because it is surrounded by two "[[" array braces, can anybody please help me out, Also im getting these array of JSON from another loop if the loop runs single time i'm getting single array brace "[" , if the loop runs multiple times i'm gettin "[[" braces...
[
[
{
"attributes":{
"id":"Task_1yett21"
},
"incoming":"SequenceFlow_112bxv0",
"outgoing":"SequenceFlow_1gkdhq3"
},
{
"attributes":{
"id":"Task_0i5lteb"
},
"incoming":"SequenceFlow_1gkdhq3",
"outgoing":"SequenceFlow_1gjii2n"
},
{
"attributes":{
"id":"Task_1v37yfe"
},
"incoming":"SequenceFlow_1gjii2n",
"outgoing":"SequenceFlow_0bygyft"
}
]
]
I'm calling this function to get the JSON objects in the above array...
var getAllValuesOfKey = function (dataObj, queryKey) {
var resultArr = [];
if (!queryKey) {
return resultArr;
}
function execute(dataObj, queryKey) {
Object.keys(dataObj).forEach(function (key, index) {
if (typeof dataObj[key] == 'object' && !(dataObj[key] instanceof Array)) {
if (key == queryKey) {
resultArr.push(dataObj[key]);
}
execute(dataObj[key], queryKey);
} else if (key == queryKey) {
resultArr.push(dataObj[key]);
}
});
}
execute(dataObj, queryKey);
return resultArr;
}
var searchKey = 'task';
var result=getAllValuesOfKey(obj1, searchKey);
You can select the inner array in your loop with index 0 on the outer array, like this:
var myDoubleArray: any = [[{...}, {...}, {...}]];
for (let i = 0; i < myDoubleArray[0].length; i++) {
console.log(myDoubleArray[0][i].attributes.id);
}
If the arrays are still in JSON format, you need to first parse them to JavaScript before you can loop through the data. This can be done with JSON.parse().
var arr = [
[
{
"attributes":{
"id":"Task_1yett21"
},
"incoming":"SequenceFlow_112bxv0",
"outgoing":"SequenceFlow_1gkdhq3"
},
{
"attributes":{
"id":"Task_0i5lteb"
},
"incoming":"SequenceFlow_1gkdhq3",
"outgoing":"SequenceFlow_1gjii2n"
},
{
"attributes":{
"id":"Task_1v37yfe"
},
"incoming":"SequenceFlow_1gjii2n",
"outgoing":"SequenceFlow_0bygyft"
}
]
]
for (var i in arr[0]) {
//arr[0][i].attributes.id will give you the id
console.log(arr[0][i].attributes.id);
}
How to get key of a json which resides within a array based on value, say if the value as ValueB it should return MainB
var app = angular.module('myApp', []);
app.controller('ArrayController', function ($scope) {
$scope.myDatas = [
{
"Test1": "Value1",
"MainA": ""
},
{
"Test1": "Value2",
"MainA": "ValueB"
},
{
"Test1": "",
"MainA": "ValueC"
}
];
$scope.getJsonKey = function(jsonArray, jsonValue)
{
angular.forEach(jsonArray, function(value, index)
{
if (value.Test1 === jsonValue)
{
return "Test1";
}
if (value.MainA === jsonValue)
{
return "MainA";
}
});
};
console.log($scope.getJsonKey($scope.myDatas, "ValueB"));
});
Can anyone please tell me some solution for this
Here is a small function that should do what you want, as long as the values are unique:
var arr=[
{
"Test1": "Value1",
"MainA": "ValueA"
},
{
"Test2": "Value2",
"MainB": "ValueB"
},
{
"Test3": "Value3",
"MainC": "ValueC"
}
]
function getKey(arr, val){
for(var i=0;i<arr.length;i++){
var item= arr[i];
for(var key in item){
if(val === item[key]) return key;
}
}
return null; // not found
}
console.log(getKey(arr, 'ValueB')) // MainB
You haven't shared too much code here, so I'm not sure what the best solution would be.
However, to simply answer you question, you could use this example:
Convert JSON to a js object via $.parseJSON(), and then find your key:
function getKeyInArray(arr, val){
for(var i=0, len=arr.length;i<len;i++){
var obj = arr[i];
for(var key in obj){
if(obj[key] == val)
return key;
}
}
return null;
}
view example:
http://jsfiddle.net/wc3mhg8u/21/
Try this
$scope.getJsonKey = function(jsonArray, jsonValue)
{
angular.forEach(jsonArray, function(value, index)
{
for(var key in value) {
if (value === jsonValue)
{
return key
}
}
});
};
console.log($scope.getJsonKey($scope.myDatas, "ValueB"));
I am trying to loop over an associative JSON object using ko.utils.arrayMap(), but the function never enters the loop when the it is done in this manner. Can anyone suggest how I can get at these properties. Possible I'm using the wrong utility function for thisstyle of JSON?
http://jsfiddle.net/rVPBz/
var data = [
{
"job_id":"AM28200",
"inspection":{
"5":{
"inspection_type_id":5,
"inspection_type_name":"hydro",
"display_name":"Requested",
"html_name":"Hydro",
"itp":"Stage H1. H2, H3",
"1":{
"dates":[
"2013-10-21"
],
"inspectors":[
" "
]
},
"2":{
"dates":[
"2013-10-21"
],
"inspectors":[
" "
]
},
"3":{
"dates":[
"2013-10-21"
],
"inspectors":[
" "
]
},
"4":{
"dates":[
"2013-10-21"
],
"inspectors":[
" "
]
},
"5":{
"dates":[
"2013-10-21"
],
"inspectors":[
" "
]
}
}
}
},
{
"job_id":"AM28212",
"inspection":{
"5":{
"inspection_type_id":5,
"inspection_type_name":"hydro",
"display_name":"Waived",
"html_name":"Hydro",
"itp":"Stage H1. H2, H3",
"1":{
"dates":[
"2013-10-21"
],
"inspectors":[
" "
]
}
}
}
}
]
var InspectionDiary = function() {
var self = this;
self.jobs = ko.observableArray([])
function Job(data){
var self = this;
self.job_id = data.job_id;
self.types = ko.observableArray([])
}
function Type(data){
var self = this;
self.type_id = ko.observable(data.inspection_type_id);
self.name = ko.observable(data.inspection_type_name);
self.display_name = ko.observable(data.display_name);
self.html_name = ko.observable(data.html_name);
self.itp = ko.observable(data.itp);
self.inspectors = ko.observableArray([])
self.dates = ko.observableArray([]);
}
var jobs = ko.utils.arrayMap(data, function(item) {
var job = new Job(item);
var types = ko.utils.arrayMap(item.inspection, function(item) {
var type = new Type(item)
type.dates = ko.utils.arrayMap(item.dates(), function(item) {
return new Dates(item);
})
type.inspectors = ko.utils.arrayMap(type.inspectors(), function(item) {
return new Inspector(item);
})
return type;
})
job.types(types);
return job;
});
self.jobs(jobs);
}
ko.applyBindings(new InspectionDiary())
The ko.utils.arrayMap is designed to be used on an array, not for an object.
To loop through an object you can use the following function :
var objectMap = function(o, handler){
var res = {};
for(var key in o) {
res[key] = handler(o[key])
}
return res;
};
As the mapping doc says :
ko.utils.arrayMap, which executes a function for each item in an array and pushes the result of the function to a new array that is returned.
See fiddle
The problem is that the json does not contain arrays in the proper places. For example, inspection should be an array and it isn't. Since it looks like you aren't doing a lot of extra stuff in the viewModels, you could try this for an easier mapping from JSON to VMs: http://knockoutjs.com/documentation/plugins-mapping.html