Stringify in objects JSON inside a object JSON - javascript

This is my object JSON:
var myJSon = {
"Student": "name",
"Answers":{
"Answer1": {
"question": "question",
"answer": "black",
"time": "00:02:30",
"number_tentatives": "1"
},
"Answer2": {
"question": "question",
"answer": "black",
"time": "00:02:30",
"number_tentatives": "2"
}
}
};
I need to fill in the object "Answer1" or "Answer2". I tried
myJSon.Respostas = JSON.stringify("One","hello","00:03:22","1");
But this results in {Student":"\"name\"","Answers":"\"oi\"}
What I would like is {"Student": "\"name\"", "Answers": {"Answer1": {"question": "One", "answer": "hello" ,"time":"00:03:22" ,"number_tentatives": "1"}, "

If you have an object containing multiple answers, it should be an array or map of answers.
Let's think of your object's initial state as this:
var myJson = {student: 'Student Name', answers: []};
So then you could start filling the answers array like:
myJson.answers.push({question: 'q', answer: 'a', time: 1, number_tentatives: 1});
If you'd now access myJson.answers it would be an array with one answer in it.
If you still think the way to go would be objects (so a 'key' is assigned to each answer), you would do this, instead of push:
myJson.answers['answer1'] = {question: 'q', answer: 'a', time: 1, number_tentatives: 1};

If you want to add additional data, then you could try this:
myJSon.Answers.Answer3 ={"question":"One","answer":"hello","time":"00:03:22","number_tentatives":"1"};
then test it like
console.log(JSON.stringify(myJSon));

Related

How to analyze/count an array of objects in Javascript

Stack Overflow! This is my very first.
So, say for example I have the following array:
[
{
"question1": "Apple",
"question2": 5,
"question3": "Item 1"
},
{
"question1": "Apple",
"question2": 4,
"question3": "Item 2"
},
{
"question1": "Orange",
"question2": 4,
"question3": "Item 2"
}
]
Each object represents a respondent's answers to each question from a survey, which means the array above has a total of 3 responses.
What I want is to count the answers of each question, like how many in a multiple choice question chose X answer and so on.
The following output should look like this for a single question:
[
{
"answer": "Apple",
"count": 2,
},
{
"answer": "Orange",
"count": 1,
}
]
Which means according to the example above I'll need total of 3 arrays (because total 3 questions) of counted answers.
Is there any way to achieve this? My goal here is to use ChartJS in React to display charts of the responses of each question.
Final output for a single chart (of a single question, say question1):
[
{
"answer": "Apple",
"count": 2,
},
{
"answer": "Orange",
"count": 1,
}
]
This outputs an array of arrays of objects, instead of multiple array variables of objects. Since JavaScript objects preserve insertion order, you don't need to worry about the questions being out of order, assuming they're already in the proper order.
const data = [{question1:"Apple",question2:5,question3:"Item 1"},{question1:"Apple",question2:4,question3:"Item 2"},{question1:"Orange",question2:4,question3:"Item 2"}];
const newData = Object.values(data.reduce((acc, qna) => {
for (const [question, answer] of Object.entries(qna)) {
acc[question] = acc[question] ?? {};
acc[question][answer] = (acc[question][answer] ?? 0) + 1;
}
return acc;
}, {}))
.map((answerCount) => Object.entries(answerCount)
.map(([answer, count]) => ({ answer, count }))
);
console.log(newData);

How can I add an element in object at certain position?

I have this object:
var ages = [{
"getasafieldDetail": {
"id": "xxx",
"asaentrySet": [{
"result": "ON",
"buy": {
"username": "Dis"
},
"offerSet": [{
"createdStr": "2001-08-09 at 11:52 pm",
"value": 5.0
}]
}]
}
}];
and i want to add an element and have an output like this:
var ages = [{
"getasafieldDetail": {
"id": "xxx",
"asaentrySet": [{
"result": "ON",
"buy": {
"username": "Dis"
},
"land": "111", // THIS <<<<------------
"offerSet": [{
"createdStr": "2001-08-09 at 11:52 pm",
"value": 5.0
}]
}]
}
}];
i tried using splice but not works...
ages.splice(ages[0]['getasafieldDetail']['asaentrySet'][0]['offerSet'],0,'"land": "111"');
ages.join();
There is the handy syntax of Destructuring assignments which helps with cutting and reassembling objects.
Edit
#FireFuro99 did point to the ES6/ES2015 spec which explicitly states how to preserve/handle an object's key-order at the object's creation time.
Thus one can say ...
Every JS engine which does support Destructuring assignment has to respect too any object's key order from/at this object's creation time.
const ages = [{
getasafieldDetail: {
id: "xxx",
asaentrySet: [{
result: "ON",
buy: {
username: "Dis",
},
offerSet: [{
createdStr: "2001-08-09 at 11:52 pm",
value: 5.0,
}],
}],
},
}];
const { result, buy, ...rest } = ages[0].getasafieldDetail.asaentrySet[0];
ages[0].getasafieldDetail.asaentrySet[0] = {
result,
buy,
land: "111",
...rest,
};
console.log({ ages });
.as-console-wrapper { min-height: 100%!important; top: 0; }
Splice only works on Arrays.
To make this work, convert your Object to an Array using Object.entries(), then use splice, and then convert it back to an object using Object.fromEntries().
const entrySet = Object.entries(ages[0]['getasafieldDetail']['asaentrySet'][0]);
entrySet.splice(2,0, ["land", "111"]);
ages[0]['getasafieldDetail']['asaentrySet'][0] = Object.fromEntries(entrySet);
This will insert the key-value pair at the the specified position.
The advantage this has over the destructuring assignment is, that you can specify the index, whereas destructuring is pretty hardcoded.
ages[0]["getasafieldDetail"]["asaentrySet"][0].land = '111' will create the key land in the first object in asaentrySet and assign the value 111. Key order is not guaranteed
var ages = [{
"getasafieldDetail": {
"id": "xxx",
"asaentrySet": [{
"result": "ON",
"buy": {
"username": "Dis"
},
"offerSet": [{
"createdStr": "2001-08-09 at 11:52 pm",
"value": 5.0
}]
}]
}
}];
ages[0]["getasafieldDetail"]["asaentrySet"][0].land = '111'
console.log(ages)
When it is an array of objects you could simple, add, passing the position that you want by editing the array like the example below:
let land = {land: 1111}
let ages = [{'a':11},'2', 'wd']
let new =[]
new.push(ages[1])
new.push(land)
ages[1] = new
console.log(ages)
output:
(3) [{…}, Array(2), "wd"]
You get what you want from the array, edit it, and put back in the same position, may it can help.

How can I combine this data into one Object?

This one is a tricky one.
So, lets say I have two JS objects that are fetched via REST call, via two callbacks.
So, we have:
call1() - POST method - parsed JSON to JS object, route: {{url}}/data
call1.json:
"data": [
{
"id": "1",
"volume:" "2000"
},
{
"id": "2",
"volume:" "3000"
},
{
"id": "3",
"volume:" "4000"
},
{
"id": "4",
"volume:" "5000"
}
];
call2(req.body.id) - GET method - parsed JSON to JS object, route: {{url}}/data/:id
For example, if I pass req.body.id as = 1 got from the first response, it will open data for that id. So:
return call2(2) will return the data from this JSON: call2.json:
"data": [
{
"id": "1",
"add_data": "important string",
"add_data_2": "important string two"
},
];
The bottom line is, when doing the {{url}}/data route call - call() I need to serve all the data from {{url}}/data/:id routes, and bind them to the correct id. So, for example, the scenario I am trying to achieve is this:
Inside call(): get call1.json: data, do as many call2(req.body.id) calls as there are ids in the first object and then combine add_data and add_data_two values in the first object. So for example the final object would look like this.
console.log(response)
"data": [
{
"id": "1",
"volume:" "2000",
"add_data": "important string",
"add_data_2": "important string two"
},
{
"id": "2",
"volume:" "3000",
"add_data": "important string",
"add_data_2": "important string two"
},
{
"id": "3",
"volume:" "4000",
"add_data": "important string",
"add_data_2": "important string two"
},
{
"id": "4",
"volume:" "5000",
"add_data": "important string",
"add_data_2": "important string two"
}
];
This is what I have tried so far:
async get_data(req) {
try {
const objFirst = await call1(); //gets data
let objTwo = '';
for (let i = 0; i < objFirst.data.length; i++) {
objTwo = await call2({id: objFirst.data[i].id}) //gets data
}
return objFirst;
} catch(err) {
console.log("Error: ", err)
}
}
But it does not work. How can I get all data, and make as many as call2(id) as there are ids and combine that all in one object? Basically, I need to repeat this callback -> call2(id) as many ids we receive in call1().
Thanks, sorry if it looks like a mess.
You can use the map function and spread operator for this. Something like below.
Call2 function just simulates what an endpoint would return, but you get the idea.
var data = [
{
id: 1,
add_data: "1111"
},
{
id: 2,
add_data: "2222"
}
];
var data2 = [
{
id: 1,
volume: "bla"
},
{
id: 2,
volume: "bla"
}
];
function call2(id) {
return data2.filter(x => x.id == id)[0];
}
var result = data.map(x => {
var response = call2(x.id);
return {
...x,
...response
}
})
console.dir(result[0]);
The speed of your solution (loop through an array and doing http calls to get more data is really slow). If you have a lot of these functions that needs to combine data from different datasources, and depending on your project size, i would look into either RXJS or GraphQL (If you really need performance). RXJS have great functions to merge, combine, map etc data.
RXJS
GraphQL

Convert Javascript response to Array/Map

I have the following response from a Javascript ElasticSearch Query, and i need to map it to the below structure. Is there a more efficient way to do this than what I am currently doing?
Thanks
Structure I need to map to: (about 700 of these)
[{
"coordinates": ["48", "37"],
"name": "something",
"population": "501"
},
Current structure of my data being returned:
[Object, Object, Object, Object, Object, Object, Object, Object, Object, Object]
0: Object
_id: "4"
_index: "locationIndex"
_score: 1
_source: Object
coordinates: Array[2]
0: -77.080597
1: 38.892899
length: 2
__proto__: Array[0]
name: "someName"
population: 57205
1: Object
...
What I'm trying but fails:
var results= [{
"key": 'coordinates',
resp.coordiantes[0],
resp.coordinates[1],
"key": 'name',
resp.name
})
}];
Assuming that your data is stored inside a myData variable, you can use the Array.prototype.map method to manipulate it and achieve what you want. Here's a solution:
result = myData.map(function(obj) {
return {
coordinates: obj._source.coordinates,
name: obj.name,
population: obj.population
}
});
Simple as this! The result will be something like this:
[
{
"coordinates": [-77.080597, 38.892899],
"name": "some name",
"population": 52701
},
{
"coordinates": [-54.930299, 30.992833],
"name": "some name 2",
"population": 84229
},
{
"coordinates": [-82.001438, -5.38131],
"name": "some name 3",
"population": 5991
} //, ...
]
It looks like you don't quite understand Object syntax in Javascript; in order for my answer to make the most sense, you may wish to read up a little on them.
Now that you understand Objects more, it should become quite clear that what you want looks something like:
var results = [];
for (var i = 0, len = data.length; i < len; i++)
{
var resp = data[i];
results.push({
'coordinates':resp['source']['coordinates'],
'name':resp.name,
'population':resp.population
});
}
For bonus points, you could include a JS framework like jQuery and just uase a map function.
I like Marcos map solution the most but also possible and quick is to use Array.from(data). This helped me in the past to convert the response API data that should be an array but wasn't yet.
I am the author of the open source project http://www.jinqJs.com.
You can easily do something like this to do what you want.
var result = jinqJs().from(data5).select(function(row){
return {coordinates: [row.coordinates[0]['0'], row.coordinates[0]['1']],
name: row.name,
population: row.population
}
});

Basic Javascript for Quiz [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 8 years ago.
Improve this question
I am creating a very basic quiz app using Javascript and was wondering what would be the best way to nest arrays/objects. I have done this before with just simple one level nesting but feel that this project might need more.
The quiz needs to have 5 questions with multiple answers. Each answer will have a points value associated with it. When the quiz has been completed it will take the average of the points to then give you a type ie. 'You nostly ticked A's', 'You mostly ticked B's' etc. Similar to the quizzes you get in magazines.
I believe it should be something like this:
var quizList = {
"question": "What's your favourite Color",
"answers": {
["a","Blue","2"],
["b","Green","4"],
["c","Red","6"],
["d","Orange","8"],
},
"question": "What's your favourite Animal",
"answers": {
["a","Dog","2"],
["b","Cat","4"],
["c","Caterpiller","6"],
["d","Donkey","8"],
}
};
Is this correct and if so how would I call the various array elements?
Is this correct
Not really. That's not an array, it's an object literal which contains nested object literals and arrays. It also contains a pretty large problem; you're overwriting the previous question/answers keys with each new question/answer. You can't have two properties with the same name in an object. You've effectively done this:
{ a: 'b', a: 'c' }
Which is going to throw out the 'b' and set a to 'c'.
You probably need to rethink the structure so the top-level element is an array:
var quizList = [
{
"question": "What's your favourite Color",
"answers": [
["a","Blue","2"],
["b","Green","4"],
["c","Red","6"],
["d","Orange","8"],
]
}, {
"question": "What's your favourite Animal",
"answers": [
["a","Dog","2"],
["b","Cat","4"],
["c","Caterpiller","6"],
["d","Donkey","8"],
]
}
];
... and if so how would I call the various array elements?
And you can't "call" these array elements. They're not executable code, they're dumb data. You need to write a program which uses this object as its input, and generates a <form> containing a series of <input> or <select> elements.
I believe that the the best way would be something like this:
var quizList = [{
question: "What's your favourite Color",
alternatives: [
{ letter: "a", text: "Blue", value: "2" },
{ letter: "b", text: "Green", value: "4" },
{ letter: "c", text: "Red", value: "6" },
{ letter: "d", text: "Orange", value: "8" },
]
}, {
/* other question */
}];
As pointed, your quizList is not an array.
This part is invalid:
"answers": {
["a","Dog","2"],
["b","Cat","4"],
["c","Caterpiller","6"],
["d","Donkey","8"],
}
answers is an object (because of the {}), so it needs to have a key and a value. Perhaps you meant this:
"answers": [
["a","Dog","2"],
["b","Cat","4"],
["c","Caterpiller","6"],
["d","Donkey","8"],
]
Which is now an array which contains 4 nested arrays.
But I'd rather change it to this:
"answers": [{
letter: "a",
text: "Dog",
value: "2"
},
//...etc
]
By making your options objects rather than arrays, you have a more robust way to get at the properties for each answer. So instead of:
var letter = someAnswer[0]; // is this the right index??
You can do this:
var letter = someAnswer.letter; // now I know it's the right one
Your code will be much easier to maintain this way and you won't have to remember which index is which part of your answer.
Overall, I'd go with something like this:
var quizList = [{
question: "What's your favourite Color",
answers: [{
letter: "a",
text: "Dog",
value: "2"
},
// etc
]
},
// etc
];
Now at the top level quizList is an array of objects and each object has a property question and another property answers which is an array of objects with properties letter, text and value.
var quizList={
"questions":[
{
"question": "What's your favourite Color",
"answers": {
"a":{
"text":"Blue",
"point":"2"
},
"b":{
"text":"Green",
"point":"4"
},
"c":{
"text":"Red",
"point":"6"
}
"d":{
"text":"Orange",
"point":"8"
}
}
},
{
"question": "What's your favourite Animal",
"answers": {
"a":{
"text":"Dog",
"point":"2"
},
"b":{
"text":"Cat",
"point":"4"
},
"c":{
"text":"Monkey",
"point":"6"
}
"d":{
"text":"Donkey",
"point":"8"
}
}
}
]
};
Try this with a json format.

Categories