For instance I have some JSON data like below (The JSON data is just an example, I just want to give out some fake, make up and wrong format JSON as example)
cata :[{
name:test1,
data:['abc1, abc2' , 'abc3,abc4']
}
name:test2,
data:['abc5, abc6' , 'abc7,abc8']
}]
And indeed I need to render it to frontend, therefore I made a new object and try to push data into it
var name = "";
var key= [];
for(var i=0;i<2;i++){
name .push(cata[i].name)
key.push(cata[i].data.join(' + '));
}
var rehandle = {
name : name,
key : key
}
The above is just how i do it now, and which do no provide the desire result, i want to know how could i restore it so i can change the format from
['abc5, abc6' , 'abc7,abc8']
to
abc5+abc6 , abc7+abc8
UPDATE version of the question:
I think i better explain it step by step:
I have some raw data
I have a row of "data" in each set of data
(E.g:data:['abc1, abc2' , 'abc3,abc4'])
I want to change it's format to abc1+abc2 , abc3+abc4 and store it to another variable
I will pass the variable store abc1+abc2 , abc3+abc4 to an object
5.Render it one by one in a table
UPDATE 2
I have seen #pill's answer, am i able to render the data like
for(var i=0;i<cata.length;i++){
var trythis = trythis + '<td>'+name[i]+'</td>' + '<td>'+data[i]+'</td>'
}
To format your data from
['abc5, abc6' , 'abc7,abc8']
to
abc5+abc6 , abc7+abc8
you'd simply use
data.map(k => k.split(/,\s*/).join('+')).join(' , ')
or the ES5 version
data.map(function(k) {
return k.split(/,\s*/).join('+');
}).join(' , ');
For example...
var cata = [{"name":"test1","data":["abc1, abc2","abc3,abc4"]},{"name":"test2","data":["abc5, abc6","abc7,abc8"]}];
var rehandle = cata.reduce(function(o, d) {
o.name.push(d.name);
o.key.push(d.data.map(function(k) {
return k.split(/,\s*/).join('+');
}).join(' , '));
return o;
}, {
name: [],
key: []
});
console.log('rehandle:', rehandle);
Note that I had to fix up your data formatting
Related
I don't know what's wrong with the code. it works fine and both array have data. but i don't understand why the output found undefined from var _city array as it passed data to the city field.
How can I fix this?
var city = {
_country : _city
};
I'm wondering what you read that made you possibly believe that by writing what you did you would magically have an object keyed with one array with values from a second...
Essentially what is happening when you did when you
var city = {
_country : _city
};
is create an object that looks like
var city = {
'_country' : ['your', 'array', 'of', 'cities']
};
that is to say, an object with one key, '_country' mapped to an array of cities.
This explains why you get undefined... city['any string that isn't exactly " _country"'] == undefined
What you want to do is more likely,
var city = _country.reduce(function(acc, cur, idx) { acc[cur] = _city[idx]; return acc; }, {});
It's because _country is already defined above:
var _country = ["Afghanistan","Bahrain","Canada","Denmark","Ethiopia","France","Germany","Hong Kong","India","Japan"];
Change the definition within city to something else (maybe country):
var city = {
country: _city,
};
And it'll work.
My Link json test file is the following:
[{"google" : "https://google.com"},{"bing" : "https://bing.com"}]
The javascript requesting the value, using axios:
var Links = './Links'
axios.get(Links)
.then(function(response){
console.log(response.data["google"]);
try {
var Test12 = JSON.stringify(response.data["google"]);
} catch (err) {
var Test12 = 'nothing'
}
The result is undefined.
My goal is to return the value of the input "google" or any input from the JSON and store it in the var as a string.
Since its an array of objects so you should access the values like,
response.data[0].google
OR
response.data[0]["google"]
Your data file is a list with two objects in it.
To access the google item you should access the list element.
var Test12 = JSON.stringify(response.data[0]["google"]);
Although I would change the json file to:
{"google" : "https://google.com", "bing" : "https://bing.com"}
Maybe like this:
var data=[{"google" : "https://google.com"},{"bing" : "https://bing.com"}];
data.forEach(function(el, index) {
Object.keys(el).forEach(function(val) {
console.log(val + " => " + el[val]);
});
});
This is my JSON, I want to directly get the zipCodes values from the JSON without looping through the JSON. How can I do it?
countries:[
{
name:'India',
states:[{
name:'Orissa',
cities:[{
name:'Sambalpur',
zipCodes:{'768019','768020'}
}]
}]
}
]
I think you are looking for
countries[0].states[0].cities[0].zipCodes
Please note, this works for the above JSON as there is only 1 country in countries array and same as for states and cities. However, if there are more than 1 country, state or city then, you will have to iterate to extract information until and unless you know the exact index.
As this is not an associative array, your option is only to use indexes like this:
countries[x].states[y].cities[0].zipCodes
Where x would be each representation of state in your array, in case, of course, that you have more than one.
Similarly y would be each state in each state in each country, in case you have more of those and you can do the same for cities if you need to.
EDIT:
Here's how you can iterate the array:
for(var c in countries)
{
var name = countries[c].name;
if (name === "CountryIAmLookingFor")
{
var statesList = countries[c].states;
for (var s in statesList)
{
var stateName = statesList[s].name;
.....
}
}
}
You can keep iterating until you find the country, state, and city you need, then extract the zipCodes from there as shown in the previous code snippet.
Without "looping"
You can do this crazy trick (not saying this is the best way, but this way you aren't looping through the JSON):
var myData = { 'Put Your Data': 'HERE' };
function getCodes(name, data) {
var sv = data.match(new RegExp(name+'([\\S\\s]*?}][\\S\\s]*?}])'))[1].match(/zipCodes":\[(.*?)\]/g), r = [];
sv.forEach(function (item) {
item.match(/\d+/g).forEach(function (sub) {
r.push(+sub);
});
});
return r;
}
getCodes('India', JSON.stringify(myData));
If your data is already string, then you don't need the JSON.stringify. The forEach you see isn't actually "looping" through the JSON. It's already extracted the zip codes and the code just adds the zip codes to the array. . This line:
var sv = JSON.stringify(data).match(new RegExp(name+'([\\S\\s]*?}][\\S\\s]*?}])'))[1].match(/zipCodes":\[(.*?)\]/g), r = [];
is what grabs the zip codes, it gets something like:
["zipCodes":["768019","768020"]"]
The next line:
item.match(/\d+/g)
will grab the numbers outputting something like:
["768019", "768020"]
The loop just adds the zip-codes to another array
With looping
You're better off looping through the JSON:
var myData = {}, // Your data
zips = [];
myData.countries.forEach(function(i) {
if (i.name === 'India') {
i.states.forEach(function(j) {
j.cities.forEach(function(l) {
l.zipCodes.forEach(function(m) {
zips.push(m);
});
});
});
}
});
//use "zips" array
PERFORMANCE AND SPEED TESTS
After testing copying an array about 500MB (half a gig) took about 30 seconds. That's a lot. Considering an extremely large JSON would be about ~5MB, looping through a little over 5MB of JSON takes about 0.14 seconds. You should never worry about speed.
Here's my "trick" for avoiding explicit iteration. Let JSON.parse or JSON.stringify do the work for you. If your JSON is in string form, try this:
var array = [];
JSON.parse(jsonString, function (key, value) {
if (key === "zipCodes") {
array = array.concat(value);
}
return value;
});
console.log(array); // all your zipCodes
Suppose your Json is like
countries =[
{
name:'India',
states:[{
name:'Orissa',
cities:[{
name:'Sambalpur',
zipCodes:768019768020
}]
},{
name:'mumbai',
cities:[{
name:'rea',
zipCodes:324243
}]
}]
}
]
So now we use MAP it will give you ZipCode of every cities
countries.map(function(s){
s.states.map(function(c){
c.cities.map(function(z){
console.log(z.zipCodes)
})
})
})
OR
If you use return statement then it will give you 2 array with two zip code as per over JSON
var finalOP = countries.map(function(s){
var Stalist = s.states.map(function(c){
var zip = c.cities.map(function(z){
return z.zipCodes
})
return zip
})
return Stalist
})
console.log(finalOP)
I know there are 1 million and 1 questions on this, but I cannot seem to find an answer.
I am receiving data via PHP as such
echo json_encode($result);
From a typical MYSQL query.
I get the result back like this in the console.
[{"id" : "1", "name" : "bob"}]
I am trying to use $.each to iterate through this so I can process my results but I only get errors, undefineds or 0[object Object].. things like that.
My goal is to append each value to a input box (retrieving data from a table to put into an edit box).
$.post('getstuff.php', { id : id } function(data){
$.each(data), function(k,v){
$('input[name= k ]').val(v);
});
});
As you can see i was hoping it was as simple as a key=>value pair but apparantly not. I have tried parsing, stringifiying.. really I am lost at this point. I also cannot tell $.post that I am using JSON because I am using a more arbitrary function, but am just posting that as my example.
Edit
var retrievedData = JSON.parse(data);
$.each(retrievedData, function(k,v){
for (var property in retrievedData) {
if (retrievedData.hasOwnProperty(property)) {
console.log(k);
console.log(v);
console.log(property);
//$('input[name= k ]').val(v);
}
}
});
In your second code sample, retrievedData is an array, which you iterate using jQuery $each...
$.each(retrievedData, function(k, v) {
OK so far. But then you try to iterate retrievedData again like an object, which it isn't. This is why you are getting undefined messages in the console
for (var property in retrievedData) {
if (retrievedData.hasOwnProperty(property)) {
console.log(k);
console.log(v);
console.log(property);
//$('input[name= k ]').val(v);
}
}
On the inner loop you should be iterating v not retrievedData. On each pass of $each v will be an object.Try this:
$.each(retrievedData, function(k,v){
for (var key in v) {
if (v.hasOwnProperty(key)) {
console.log("key: " + key);
console.log("value: " + v[key]);
}
}
});
You should do some type checking that v is an object first and catch any errors.
Use either :
$.ajax({
'dataType' : 'json'
});
Or
$.getJSON
Or if you want to use $.post, just do in your success function :
var good_data = JSON.parse(data);
$.each(good_data, function(k,v) {
$('input[name= k ]').val(v);
});
Answering your question based on your comments on other answer.
My assumption is you are getting data as JSON,if not you need to parse it,for that you can use JSON.parse(string).
Here I'm using Underscore.js
var data=[{"id" : "1", "name" : "bob"}]
$(data).each(function(ind,obj){
var keys=_.keys(obj);
$(keys).each(function(i,ke){
console.log(ke)
console.log(obj[ke]);
})
});
Here is JSFiddle of working code
First you need to define you're expecting JSON in your POST request - http://api.jquery.com/jQuery.post/
Then you need to iterate through the response.
$.post('getstuff.php', { id : id } function(data){
//Assuming you get your response as [{"id" : "1", "name" : "bob"}], this is an array
//you need to iterate through it and get the object and then access the attributes in there
$.each(data), function(item){
$('input[name=' + item.name + ']').val(item.id);
});
}, 'json');
EDIT
If you want to iterate over the properties of the objects returned, you need to put another loop inside the $.each
for (var property in item) {
if (object.hasOwnProperty(property)) {
// do stuff
}
}
More about it here - Iterate through object properties
EDIT 2
To address the solution you've posted. You've used the wrong variable names. Here's a working fiddle - http://jsfiddle.net/EYsA5/
var $log = $('#log');
var data = '[{"id" : "1", "name" : "bob"}]'; //because we're parsing it in the next step
var retrievedData = JSON.parse(data);
for (var parentProp in retrievedData) { //this gets us each object in the array passed to us
if (retrievedData.hasOwnProperty(parentProp)) {
var item = retrievedData[parentProp];
for (var property in item) { //this gives us each property in each object
if (item.hasOwnProperty(property)) {
console.log(item[property]);
$log.prepend("<br>");
$log.prepend("Property name is - " + property);
$log.prepend("<br>");
$log.prepend("Value of property is - " + item[property]);
//do stuff
}
}
}
};
I have a servlet which talks with the database then returns a list of ordered (ORDER BY time) objects. At the servlet part, I have
//access DB, returns a list of User objects, ordered
ArrayList users = MySQLDatabaseManager.selectUsers();
//construct response
JSONObject jsonResponse = new JSONObject();
int key = 0;
for(User user:users){
log("Retrieve User " + user.toString());
JSONObject jsonObj = new JSONObject();
jsonObj.put("name", user.getName());
jsonObj.put("time", user.getTime());
jsonResponse.put(key, jsonObj);
key++;
}
//write out
out.print(jsonResponse);
From the log I can see that the database returns User objects in the correct order.
At the front-end, I have
success: function(jsonObj){
var json = JSON.parse(jsonObj);
var id = 0;
$.each(json,function(i,item) {
var time = item.time;
var name = item.name;
id++;
$("table#usertable tr:last").after('<tr><td>' + id + '</td><td width="20%">' + time +
'</td><td>' + name +
'</td></tr>');
});
},
But the order is changed.
I only noticed this when the returned list has large size (over 130 users).
I have tried to debug using Firebug, the "response tab" in Firebug shows the order of the list is different with the log in the servlet.
Did i do anything wrong?
EDIT: Example
{"0":{"time":"2011-07-18 18:14:28","email":"xxx#gmail.com","origin":"origin-xxx","source":"xxx","target":"xxx","url":"xxx"},
"1":{"time":"2011-07-18 18:29:16","email":"xxx#gmail.com","origin":"xxx","source":"xxx","target":"xxx","url":"xxx"},
"2":
,...,
"143":{"time":"2011-08-09 09:57:27","email":"xxx#gmail.com","origin":"xxx","source":"xxx","target":"xxx","url":"xxx"}
,...,
"134":{"time":"2011-08-05 06:02:57","email":"xxx#gmail.com","origin":"xxx","source":"xxx","target":"xxx","url":"xxx"}}
As JSON objects do not inherently have an order, you should use an array within your JSON object to ensure order. As an example (based on your code):
jsonObj =
{ items:
[ { name: "Stack", time: "..." },
{ name: "Overflow", time: "..." },
{ name: "Rocks", time: "..." },
... ] };
This structure will ensure that your objects are inserted in the proper sequence.
Based on the JSON you have above, you could place the objects into an array and then sort the array.
var myArray = [];
var resultArray;
for (var j in jsonObj) {
myArray.push(j);
}
myArray = $.sort(myArray, function(a, b) { return parseInt(a) > parseInt(b); });
for (var i = 0; i < myArray.length; i++) {
resultArray.push(jsonObj[myArray[i]]);
}
//resultArray is now the elements in your jsonObj, properly sorted;
But maybe that's more complicated than you are looking for..
As mentioned by ghayes , json objects are unordered.
There are multiple solutions to this problem.
You can use array and the sort it to get the ordered list.
You can use gson library to get the desired order of elements.
I would prefer the second option as it is easy to use.
As JSONObject is order less and internally uses Hashmap. One way to use it to download the all classes from org.json and use in your project directly by changing the internal HashMap implementation to LinkedHashMap in JSONObject.java file. below is the sorted json files
https://github.com/abinash1/Sorted-Json-Object