I have a json file like below (test.json). I am unsuccessfully trying to parse the test array and remove duplicates of any "name" below
{
"test": [{
"name": "jeb",
"occupation": "teacher"
},
{
"name": "jeb",
"occupation": "writer"
},
{
"name": "bob",
"occupation": "skydiver"
}
]
}
So far, my code is the following:
var xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
var myObj = JSON.parse(this.responseText);
var i;
var test= myObj.test.length;
for (i=0; i<=myObj.test.length; i++) {
var name = myObj.test[i].name;
var occupation = myObj.test[i].occupation;
console.log(name + " and " + occupation)
}
}
}
xmlhttp.open("GET", "test.json", true);
xmlhttp.send();
and it prints out:
jeb and teacher
jeb and writer
bob and skydiver
I would like the end result to be be:
jeb and teacher, writer
bob and skydiver
Any help is appreciated. Thank you!
It would probably be best to reduce into an object indexed by name, whose value is an array of occupations, and then once the object is created, you can iterate over it and print the occupations of each name:
const obj = {
"test": [{
"name": "jeb",
"occupation": "teacher"
},{
"name": "jeb",
"occupation": "writer"
},{
"name": "bob",
"occupation": "skydiver"
}]
};
const namesByOccupation = obj.test.reduce((a, { name, occupation }) => {
if (!a[name]) a[name] = [];
a[name].push(occupation);
return a;
}, {});
Object.entries(namesByOccupation).forEach(([name, occupations]) => {
console.log(name + ' and ' + occupations.join(', '));
});
Related
I have a json like this
var person = [{
"name": "john",
"age": 20
}, {
"name": "Samuel",
"age": 10
}, {
"name": "Jin",
"age": 10
}]
My desire output is
age 10 (2)
- Samuel
- Jin
age 20 (1)
- John
I have problem counting the total. I would do
ages.map(doList) //where ages is [10,20]
doList(age) {
persons.filter(p => p.age === age)
.map(p => {
p.name
})
}
but how do print out the length of the age group?
You might change your data structure for easier output like.
var person = [{
"name": "john",
"age": 10
}, {
"name": "Samuel",
"age": 10
}, {
"name": "Jin",
"age": 10
}];
let newArray = [];
person.forEach((p) => {
let findPreviousIndex = newArray.findIndex((itm) =>{
return itm.age == p.age;
});
if(findPreviousIndex > -1){
// previous found, push the name
newArray[findPreviousIndex].names.push(p.name);
}else{
// not found. create a new object and push it
newArray.push({
"age" : p.age,
"names" : [].concat(p.name)
})
}
});
console.log(newArray);
Now, its easy to print your grouped data and easy to find length.
Here's one way to produce the desired output, first using .reduce() to set up a result object with a property for each age that is an array of names for that age, then mapping over the properties of result to create a formatted string that gives the specific format in the question:
var person = [{
"name": "john",
"age": 20
}, {
"name": "Samuel",
"age": 10
}, {
"name": "Jin",
"age": 10
}]
var result = person.reduce((a, c) => {
(a[c.age]||(a[c.age]=[])).push(c.name)
return a
}, {})
console.log(result)
var formatted = Object.keys(result)
.map(k=>`age ${k} (${result[k].length})\n${result[k].map(n => `- ${n}`).join('\n')}`)
.join('\n\n')
console.log(formatted)
var person = [{
"name": "john",
"age": 20
}, {
"name": "Samuel",
"age": 10
}, {
"name": "Jin",
"age": 10
}];
// create a map where the key is the person's age and the value is a list of names
var ageMap = person.reduce(function(result, p) {
var key = p.age;
var name = p.name;
if (result[key]) {
result[key].push(name);
} else {
result[key] = [name];
}
return result;
}, {});
// traverse the map and print the names of people grouped by age
Object.keys(ageMap).forEach(function(key) {
var value = ageMap[key];
console.log("age " + key + " (" + value.length + ")");
value.forEach(function(name) {
console.log("- " + name);
});
console.log("");
});
JSFiddle: https://jsfiddle.net/njcms8rj/
As said above, I don't know how to use this kind of JSON response from my server-side php which I got by using this code echo json_encode(array_merge($outp, $outp2));
[
{
"stuid":"12",
"stuname":"Velino Meratis",
"stucourse":"BSIT",
"stustat":"0",
"stulyear":"4",
"stulog":"feb 16 2017"
},
{
"stuid":"13",
"stuname":"Alana Melker",
"stucourse":"BSCE",
"stustat":"1",
"stulyear":"5",
"stulog":"feb 16 2017"
},
{
"stuid":"12",
"cname":"InfoTech000",
"clog":"1"
},
{
"stuid":"12",
"cname":"InfoTech001",
"clog":"2"
},
{
"stuid":"12",
"cname":"C101",
"clog":"3"
},
{
"stuid":"13",
"cname":"CE000",
"clog":"4"
},
{
"stuid":"13",
"cname":"CE001",
"clog":"5"
},
{
"stuid":"13",
"cname":"C101",
"clog":"6"
}
]
If I use this code in my client side javascript
if (this.readyState == 4 && this.status == 200) {
students = JSON.parse(this.responseText);
students.forEach(function(item){
console.log(item.stuid);
x = item.stuid;
document.getElementById("demo").innerHTML += x + " " + item.stuname + "<br>" + item.cname + "<br>";
});
}
it just ends up giving me this:-
12 Velino Meratis
undefined
13 Alana Melker
undefined
Somehow I can iterate the stuid and the stunamebut it won't allow them to contain the cname as an array with them.
How can I turn that into something like this:-
12 Velino Meratis
InfoTech000, InfoTech001, C101
13 Alana Melker
CE000, CE001, C101
Can someone Help and Elaborate on this?
You can check if the array contains the key or not, that way you will be saved from "undefined" error.
You can do it this way
if(item.hasOwnProperty('cname'))
{
console.log(item.cname);
}
You can use this for stuname or other keys also.
You need to merge student objects in your array by unique IDs. One way to do this is to add new stuids to an array and merge it with subsequent items with same stuid. Once you have array of unique students, you can proceed with other goals.
if (this.readyState == 4 && this.status == 200) {
var students_raw = JSON.parse(this.responseText);
var students = [];
students_raw.forEach(function(item){
var existing = students.find($item => item.stuid === $item.stuid);
if (existing) {
existing = Object.assign({}, existing, item);
} else {
students.push(item);
}
});
// your print loop
students.forEach(function(item) {
var x = item.stuid;
document.getElementById("demo").innerHTML += x + " " + item.stuname + "<br>" + item.cname + "<br>";
});
}
Please note: Array.reduce() and Object.assign() are not supported widely. you may need to polyfill these methods
NOTE: This answer assumes you're willing and able to change the data coming from PHP
Credit where credit is due, this is an extension of #Magnus Eriksson's comment.
It would be preferable to keep the relevant data associated with each other. You should get better flexibility with well-formed data. Ideally, you should do this server side and present the data to the client already well formatted.
You should try and achieve something similar to the following for your output:
[{
"stuid": "12",
"stuname": "Velino Meratis",
"stucourse": "BSIT",
"stustat": "0",
"stulyear": "4",
"stulog": "feb 16 2017",
"classes": [{
"cname": "InfoTech000",
"clog": "1"
}, {
"cname": "InfoTech001",
"clog": "2"
}, {
"cname": "C101",
"clog": "3"
}]
}, {
"stuid": "13",
"stuname": "Alana Melker",
"stucourse": "BSCE",
"stustat": "1",
"stulyear": "5",
"stulog": "feb 16 2017",
"classes": [{
"cname": "CE000",
"clog": "4"
}, {
"cname": "CE001",
"clog": "5"
}, {
"cname": "C101",
"clog": "6"
}]
}];
Note I've used classes as the property name as it appears we are working with Courses and their classes.
Your javascript will now look like:
if (this.readyState == 4 && this.status == 200) {
students = JSON.parse(this.responseText);
students.forEach(function(item){
console.log(item.stuid);
x = item.stuid;
document.getElementById("demo").innerHTML += x + " " + item.stuname + "<br>" + item.classes.map(function(elem){
return elem.cname;}).join(",") + "<br>";
});
}
Note the map function won't work in IE8 and lower.
Now for a working example:
var students = [{
"stuid": "12",
"stuname": "Velino Meratis",
"stucourse": "BSIT",
"stustat": "0",
"stulyear": "4",
"stulog": "feb 16 2017",
"classes": [{
"cname": "InfoTech000",
"clog": "1"
}, {
"cname": "InfoTech001",
"clog": "2"
}, {
"cname": "C101",
"clog": "3"
}]
}, {
"stuid": "13",
"stuname": "Alana Melker",
"stucourse": "BSCE",
"stustat": "1",
"stulyear": "5",
"stulog": "feb 16 2017",
"classes": [{
"cname": "CE000",
"clog": "4"
}, {
"cname": "CE001",
"clog": "5"
}, {
"cname": "C101",
"clog": "6"
}]
}];
students.forEach(function(item){
console.log(item.stuid);
x = item.stuid;
document.getElementById("demo").innerHTML += x + " " + item.stuname + "<br>" + item.classes.map(function(elem){
return elem.cname;}).join(",") + "<br>";
});
<div id="demo"></div>
As mentioned in other answers and comments, the issue with your existing code, is not all objects in your json array have the property you're referencing.
You can try like this once also
HTML
<div id="result"></div>
SCRIPT
var dataJSON = [
{
"stuid":"12",
"stuname":"Velino Meratis",
"stucourse":"BSIT",
"stustat":"0",
"stulyear":"4",
"stulog":"feb 16 2017"
},
{
"stuid":"13",
"stuname":"Alana Melker",
"stucourse":"BSCE",
"stustat":"1",
"stulyear":"5",
"stulog":"feb 16 2017"
},
{
"stuid":"12",
"cname":"InfoTech000",
"clog":"1"
},
{
"stuid":"12",
"cname":"InfoTech001",
"clog":"2"
},
{
"stuid":"12",
"cname":"C101",
"clog":"3"
},
{
"stuid":"13",
"cname":"CE000",
"clog":"4"
},
{
"stuid":"13",
"cname":"CE001",
"clog":"5"
},
{
"stuid":"13",
"cname":"C101",
"clog":"6"
}
] ;
var arr = {};
for(var i = 0 ; i< dataJSON.length ; i++){
var ele = dataJSON[i];
if(arr[ ele.stuid ]==undefined){
arr[ ele.stuid ] = {};
}
arr[ ele.stuid ]['stuid'] = ele.stuid;
if(ele.stuname!=undefined){
arr[ ele.stuid ]['stuname'] = ele.stuname;
}
if(arr[ ele.stuid ]['cname'] == undefined){
arr[ ele.stuid ]['cname'] = [];
}
if(ele.cname!=undefined){
arr[ ele.stuid ]['cname'].push(ele.cname);
}
}
var str = '';
for(var key in arr){
var obj = arr[key];
str += obj['stuid'] +" "+obj['stuname']+'<br/>';
str += obj['cname'].toString()+'<br/>';
}
document.getElementById("result").innerHTML = str;
Thanks,
I have this JSON:
var person = {"id": "1", "name": "Michel"}
How would I return "1" when "Michel" is selected.
I have tried:
for (value in person) {
if (person.hasOwnProperty(value)) {
console.log(value+ " = " + person[value]);
}
}
You mean like this?
var person = [{"id": "1", "name": "Michel"}];
for(index=0;index<person.length;index++) {
if(person[index].name == 'Michel') {
console.log(person[index].id);
}
}
Another Way
var person = [{"id": "1", "name": "Michel"}];
var string = 'Michel';
function searchArray(str) {
var id = '';
for(index=0; index<person.length; index++) {
if(person[index].name == str) {
id = person[index].id;
}
}
return id;
}
var result_id = searchArray(string);
This is the code to form a JSON that a server expects. But there are some problems though
<!DOCTYPE html>
<html>
<body>
<script language="javascript" type="text/javascript">
<!--
//var acc = {};
var x = 10;
var y = 20;
var z = 30;
var output = [];
output[0] = {
name: "Accelerometer_X",
value: JSON.parse(x), // retrieve x
};
output[1] = {
name: "Accelerometer_Y",
value: JSON.parse(y), // retrieve y
};
output[2] = {
name: "Accelerometer_Z",
value: JSON.parse(z) // retrieve z
};
var record = [];
record[0] = {
starttime: new Date(),
output: output,
};
var observations = [];
observations[0] = {
sensor: "",
record: record,
};
var fromData = {};
fromData.version = "1.0.1";
fromData.observations = observations;
alert(JSON.stringify(fromData));
console.log(JSON.stringify(fromData));
//-->
</script>
</body>
</html>
The output JSON is:
{
"version": "1.0.1",
"observations": [
{
"sensor": "",
"record": [
{
"starttime": "2014-08-15T16:01:34.711Z",
"output": [
{
"name": "Accelerometer_X",
"value": 10
},
{
"name": "Accelerometer_Y",
"value": 20
},
{
"name": "Accelerometer_Z",
"value": 30
}
]
}
]
}
]
}
But the expected JSON is:
{
"version": "1.0.1",
"observations": [
{
"sensor": "",
"record": [
{
"starttime": "1-JAN-2014 15:30:00 IST",
"output": [
{
"name": "Accelerometer_X",
"value": "10"
},
{
"name": "Accelerometer_Y",
"value": "20"
},
{
"name": "Accelerometer_Z",
"value": "30"
}
]
}
]
}
]
}
The values in expected JSON is within "" ie.
{
"name": "Accelerometer_Z",
"value": "30"
}
But the produced JSON is :
{
"name": "Accelerometer_Z",
"value": 30
}
And there is another problem that is the starttime. The expected starttime format is
1-JAN-2014 15:30:00 IST
The produced starttime is:
2014-08-15T16:01:34.711Z
I do not know how to change this. Please help me out.
You shouldn't use JSON.parse on the values that you want to put in the object. The JSON.parse method is used to parse a JSON string into an object, but the values are not JSON strings.
Remove the JSON.parse call (as it doesn't change the value), and use the toString method to turn the values into strings:
output[0] = {
name: "Accelerometer_X",
value: x.toString(),
};
output[1] = {
name: "Accelerometer_Y",
value: y.toString(),
};
output[2] = {
name: "Accelerometer_Z",
value: z.toString()
};
There is no build in function that formats the date that way, you would need to make your own. Something like:
function formatDate(d) {
return d.getDate() + '-' + (d.getMonth() + 1) + "-" + d.getFullYear() + " " + d.getHours() + ":" + d.getMinutes() + ":" + d.getSeconds() + " IST";
}
Usage:
record[0] = {
starttime: formatDate(new Date()),
output: output,
};
This is the code so far working:
<!DOCTYPE html>
<html>
<body>
<script language="javascript" type="text/javascript">
<!--
//var acc = {};
var x = 10;
var y = 20;
var z = 30;
//var accString = JSON.stringify(acc); // that's what you have
var output = [];
output[0] = {
name: "Accelerometer_X",
value: x.toString(), // retrieve x
};
output[1] = {
name: "Accelerometer_Y",
value: y.toString(), // retrieve y
};
output[2] = {
name: "Accelerometer_Z",
value: z.toString() // retrieve z
};
var record = [];
record[0] = {
starttime: new Date(),
output: output,
};
var observations = [];
observations[0] = {
sensor: "",
record: record,
};
var fromData = {};
fromData.version = "1.0.1";
fromData.observations = observations;
alert(JSON.stringify(fromData));
console.log(JSON.stringify(fromData));
//-->
</script>
</body>
</html>
But the time is having problem still now. Anyone to resolve this issue?
I need to retrieve email field from JSON with JavaScript.
Here is the code:
"contacts": [
{
"addedAt": 1332358711001,
"vid": 1,
"properties": {
"lastname": {
"value": "Mott"
},
"firstname": {
"value": "Adrian"
}
},
"identity-profiles": [
{
"vid": 1,
"identities": [
{
"type": "EMAIL",
"value": "test-fdfc6c2e-e19e-4138-8201-8342ca333aa1#hubspot.com",
"timestamp": 1332358711715
},
{
"type": "LEAD_GUID",
"value": "f3ebaf07-1c6d-4ada-af31-3559dd8b3027",
"timestamp": 1332358711771
}
]
}
]
}]
The code works with all fields, except when I get to Identities, it returns NULL or unidentified.
var temp = fields.contacts.length;
for (var i=0; i<fields.contacts.length; i++){
var addedAt = fields.contacts[i].addedAt;
var formattedDate = Utilities.formatDate(new Date(addedAt), "GMT", "yyyy-MM-dd");
var lastName = fields.contacts[i].properties.lastname.value;
var firstName = fields.contacts[i].properties.firstname.value;
var vid = fields.contacts[i].vid;
var ip = fields.contacts[i]['identity-profiles'];
var id = ip.identities;
}
var id always returns unidentified. Also doesn't work:
for (var j=0; i<id.length; j++){
if(typeof ['type'] == 'EMAIL'){
var email = id[j].value;
}
};
fields.contacts[i]['identity-profiles'] is an array, it doesn't directly have a identities property.
You may want
var id = ip[0].identities;
or you should iterate over fields.contacts[i]['identity-profiles'] but it's not clear what you precisely want.