I have following array (foodDetailsList)
[{"food_id": 5, "quantity": 100, "quantity_unit": gm},
{"food_id": 45, "quantity": 200, "quantity_unit": gm},
{"food_id": 22, "quantity": 300, "quantity_unit": gm}]
Out of which, I wish to create following variable String as an OUTPUT:
'food[0][food_id]': '5',
'food[0][quantity]': '100',
'food[0][quantity_unit]': 'gm',
'food[1][food_id]': '45',
'food[1][quantity]': '200',
'food[1][quantity_unit]': 'gm',
'food[2][food_id]': '45',
'food[2][quantity]': '200',
'food[2][quantity_unit]': 'gm'
I wanted to try something like following:
const createString = ()=>{
let finalFoodList =[];
foodDetailsList.map((food,key) =>{
finalFoodList.push({
'food['+[key]+'][food_id]'`:food.id,
'food['+[key]+'][quantity]'`:food.quantity
});
});
console.log("final variable is : ",finalFoodList.toString);
}
Need to improve above code syntatically so that above output is received.
You can use the map function to iterate over your original array, then use Object.keys to get all keys of the contained food-objects and map over those keys as well to get a generic solution like this:
const foodList = [
{"food_id": 5, "quantity": 100, "quantity_unit": 'gm'},
{"food_id": 45, "quantity": 200, "quantity_unit": 'gm'},
{"food_id": 22, "quantity": 300, "quantity_unit": 'gm'}]
const foodString = foodList.map((food, index) =>
Object.keys(food).map(key => `'food[${index}][${key}]': '${food[key]}'`).join('\n')
).join('\n');
console.log(foodString);
The join()-Method joins all array-members as string with linebreaks as separators.
You can use .map() on your arr of objects. For each object you can destructure it to obtain the food_id, quantity and quantity_unit properties. Based on that, you can return a string in the format which you desired, using the index i provided in the .map() callback as the index for food in your string. Once you have obtained an array of strings, you can join each string using .join('\n').
See example below:
const arr = [{"food_id": 5, "quantity": 100, "quantity_unit": 'gm'},
{"food_id": 45, "quantity": 200, "quantity_unit": 'gm'},
{"food_id": 22, "quantity": 300, "quantity_unit": 'gm'}];
const res = arr.map(({food_id, quantity, quantity_unit}, i) =>
`'food[${i}][food_id]': '${food_id}'\n'food[${i}][quantity]': '${quantity}'\n'food[${i}][quantity_unit]': '${quantity_unit}'`
).join('\n');
console.log(res);
try this:
const foodList = [
{"food_id": 5, "quantity": 100, "quantity_unit": gm},
{"food_id": 45, "quantity": 200, "quantity_unit": gm},
{"food_id": 22, "quantity": 300, "quantity_unit": gm}
];
const createString = () => {
const foodLen = foodList.length;
let finalFoodList = foodList.map((food, index) => {
return index !== foodLen ? (
`'food[${index}][food_id]': '${food.food_id}',\n
'food[${index}][quantity]': '${food.quanatity}',\n
'food[${index}][quantity_unit]': '${food.quantity_unit}',\n`
) : (
`'food[${index}][food_id]': '${food.food_id}',\n
'food[${index}][quantity]': '${foof.quanatity}',\n
'food[${index}][quantity_unit]': '${food.quantity_unit}'
);
});
}
get length of foodList array.
map function creates new array.
second parameter in map function gives current iteration number.
we use ternary operator to return conditional output.
Related
I'm using api to get the response array, I'm trying to map the "id" under the "quiz_records" array but it returns undefined. I think that my code are correct.
This is my attempt.
array
"quizRemarks": [
{
"id": 160,
"user_id": 1,
"quiz_id": 18,
"module_id": 29,
"number_of_correct_answers": 2,
"created_at": "2021-10-15T03:52:52.000000Z",
"updated_at": "2021-10-15T03:52:52.000000Z",
"time_started": null,
"time_finished": null,
"remarks": 1,
"quiz_records": [
{
"id": 27,
"user_scores_id": 160,
"question_id": 2,
"user_answers": "DriverPH",
"remarks_correct_incorrect": "1",
"created_at": null,
"updated_at": null,
"question_text": "What is the name of this application?"
},
{
"id": 28,
"user_scores_id": 160,
"question_id": 2,
"user_answers": "Red",
"remarks_correct_incorrect": "1",
"created_at": null,
"updated_at": null,
"question_text": "What traffic light color tells you to stop before the intersection?"
}
]
}
]
ts
this.quiz_records = res['quizRemarks'].map(res => res['quiz_records'].id);
console.log(this.quiz_records);
quizRemarks is an array of objects containing an array of quiz_records. Try this to get a flat list of ids of quiz_records:
this.quiz_records = [];
this.quizRemarks.forEach(remark => {
this.quiz_records.push(...remark.quiz_records.map(rec => rec.id));
});
Below code will work----
this.quiz_records = res['quizRemarks'].map(res => res['quiz_records'].map(r => r.id));
You're truing to get an id property from an array, what it inpossible.
You can use nested map + flat() array method.
const result = res['quizRemarks'].map(remarks => {
return remarks['quiz_records'].map(record => record.id);
}).flat();
I have a json array as follows
var arrayVal = [{id:"1",name:"A", sAge: 20, eAge:30},{id:"2",name:"B", sAge: 30, eAge:50},{id:"2",name:"B", sAge: 20, eAge:40},{id:"3",name:"C", Aage: 20, eAge:50},{id:"4",name:"D", sAge: 10, eAge:30}];
I want to take difference of sAge and eAge of each id and sum the final value if there are multiple diff values of same id. For that I have the following code
const ages = array.reduce((a, {id, sAge, eAge}) => (a[id] = (a[id] || 0) + eAge - sAge, a), {});
console.log(ages);
output of the above code snippet is as follows
{
"1": 20,
"2": 50,
"3": 20,
"4": 10
}
But If I want to obtain an array as follows after using reduce(), how can I achieve that?
[{id:"1",name:"A", hours:"20"},{id:"2",name:"B", hours:"50"},{id:"3",name:"C", hours:"20"},{id:"5",name:"D", hours:"10"}]
The following does the job but I didn't obtain your expected values
var arrayVal = [{id:"1",name:"A", sAge: 20, eAge:30},{id:"2",name:"B", sAge: 30, eAge:50},{id:"2",name:"B", sAge: 20, eAge:40},{id:"3",name:"C", sAge: 20, eAge:50},{id:"5",name:"D", sAge: 10, eAge:30}];
const ages = Object.values(arrayVal.reduce((a, {id, name, sAge, eAge}) => {
let difference = eAge - sAge;
if(a.hasOwnProperty(id)) {
a[id].hours+= difference;
} else {
a[id] = {
id:id,
name:name,
hours:difference
}
}
return a;
}, {}));
Output
[
{
"id": "1",
"name": "A",
"hours": 10
},
{
"id": "2",
"name": "B",
"hours": 40
},
{
"id": "3",
"name": "C",
"hours": 30
},
{
"id": "5",
"name": "D",
"hours": 20
}
]
I have array data like this:
work_list = {
"data": {
"1": {
"team": "Design",
"members": nil,
"workload": {
"process": {
"total": 50,
"finish": 36,
"un_finish": 14,
}
}
},
"2": {
"team": "Account",
"members": 15,
"workload": {
"process": {
"total": 30,
"finish": 20,
"un_finish": 10,
}
}
}
}
}
I want to calculte total amount of work both team by:
list = work_list["data"]
count = 0
list.each do |num|
num.each do |details|
work = num["workload"]["process"]["total"]
count += work
end
end
puts "The total amount of works: #{count}"
The error here is: "undefined method `each' for nil:NilClass (NoMethodError)"
The problem with your code is that you're using : to build a hash:
"workload": {
"process": {
"total": 50,
"finish": 36,
"un_finish": 14,
}
}
Which is valid syntax in Ruby, but the keys of this hash are going to be symbols, not strings as expected, so you need to access the data of this hash by symbols:
data_hash = work_list[:"data"]
count = 0
data_hash.each do |index, data|
work = data[:"workload"][:"process"][:"total"]
count += work
end
puts "The total amount of works: #{count}"
If you want to use strings, you need to construct hash as following:
"workload" => {
"process" => {
"total" => 50,
"finish" => 36,
"un_finish" => 14,
}
}
You are iteration over a hash not array
list.each do |num, info|
work = info["workload"]["process"]["total"]
count += work
end
In the Flex app, the metadata is loaded as xml which has very good functions for searching deep into the xml nodes. In the extjs version I have converted the xml data to json, keeping the deep hierarchical content, and am loading to an extjs Store using a json reader. I have not created a model, deeming this not necessary as the model does not add add any search functionality(?). I am looking at store.find, store.findBy which can use a function, store.findRecord etc, but these functions look very 'one-levelish'. I need to go to the 'Tabs' "node", find its child 'Tab' with 'Name' of 'Tab1', and find the value of its attribute 'Title' ... am using the description "node" but it is hierarchical json data. Am I missing store functionality that would do this, should I use the store's raw json data - does json have better search functionality, or shall I revert to brute-force javascript by looping through all the "nodes"? I was hoping to avoid looping and find a function of some kind. As always, tia
Well, what I understood from our comments is that you need a kinda storage to access your JSON data as quickly and easily as possible.
JSON means JavaScript Object Notation, so it's an object!
Ok, I give you two examples.
First of all, setup JSON data:
{
"users": [{
"user": {
"id": 0 ,
"name": "foo" ,
"age": 22 ,
"skills": [{
"type": "bowcrafting" ,
"skillLevel": 50 ,
"levels": [10, 25, 50, 75, 90, 95, 99, 100]
}]
}} , {
"user": {
"id": 1 ,
"name": "bar" ,
"age": 71 ,
"skills": [{
"type": "fencing" ,
"skillLevel": 32 ,
"levels": [10, 25, 50, 90, 95, 99, 100]
} , {
"type": "swordsmanship" ,
"skillLevel": 73 ,
"levels": [10, 25, 50, 75, 80, 85, 90, 95, 99, 100]
}]
}} , {
"user": {
"id": 2 ,
"name": "foobar" ,
"age": 132 ,
"skills": [{
"type": "tactics" ,
"skillLevel": 90 ,
"levels": [10, 25, 50, 90, 95, 99, 100]
} , {
"type": "carpentery" ,
"skillLevel": 86 ,
"levels": [10, 25, 50, 75, 90, 95, 99, 100]
} , {
"type": "hiding" ,
"skillLevel": 100 ,
"levels": [10, 25, 50, 65, 75, 80, 85, 90, 95, 99, 100]
}]
}
}]
}
And now here we got two ways to follow:
First way: we can imagine the above JSON saved into a file called nested-json.json and we read it with a simple store. Than, we can use findBy search to find what we need:
var jstore = Ext.create ('Ext.data.Store', {
fields: ['id', 'name', 'age', 'skills'] ,
proxy: {
type: 'ajax' ,
url: 'nested-json.json' ,
reader: {
type: 'json' ,
root: 'users' ,
record: 'user' ,
idProperty: 'id'
}
} ,
autoLoad: true
});
Ext.create ('Ext.button.Button', {
text: 'Push me' ,
renderTo: Ext.getBody () ,
handler: function (btn) {
var index = jstore.findBy (function (user, id) {
// Here's the hint
if (user.data.skills.skillLevel === 50) return id;
else return -1;
});
if (index != -1) {
// It will print 'foo' because it's the user
// that has the skillLevel equal to 50
console.log (jstore.getAt(index).get ('name'));
}
}
});
The other way is to imagine the above JSON as an object, read directly from a raw JSON data. At this point, just use it as a javascript object:
// Users model: required by JSON reader
Ext.define ('Users', {
extend: 'Ext.data.Model' ,
fields: ['id', 'name', 'age', 'skills']
});
// JSON reader
var jreader = Ext.create ('Ext.data.reader.Json', {
model: 'Users' ,
root: 'users' ,
record: 'user' ,
idProperty: 'id'
});
// Reads records directly from raw JSON
var users = jreader.readRecords ({
"users": [{
"user": {
"id": 0 ,
"name": "foo" ,
"age": 22 ,
"skills": [{
"type": "bowcrafting" ,
"skillLevel": 50 ,
"levels": [10, 25, 50, 75, 90, 95, 99, 100]
}]
}} , {
"user": {
"id": 1 ,
"name": "bar" ,
"age": 71 ,
"skills": [{
"type": "fencing" ,
"skillLevel": 32 ,
"levels": [10, 25, 50, 90, 95, 99, 100]
} , {
"type": "swordsmanship" ,
"skillLevel": 73 ,
"levels": [10, 25, 50, 75, 80, 85, 90, 95, 99, 100]
}]
}} , {
"user": {
"id": 2 ,
"name": "foobar" ,
"age": 132 ,
"skills": [{
"type": "tactics" ,
"skillLevel": 90 ,
"levels": [10, 25, 50, 90, 95, 99, 100]
} , {
"type": "carpentery" ,
"skillLevel": 86 ,
"levels": [10, 25, 50, 75, 90, 95, 99, 100]
} , {
"type": "hiding" ,
"skillLevel": 100 ,
"levels": [10, 25, 50, 65, 75, 80, 85, 90, 95, 99, 100]
}]
}
}]
});
// Here's the magic
Ext.each (users.records, function (user) {
console.log ('*** USER ***');
console.log (user);
console.log ('id: ' + user.get ('id'));
console.log ('name: ' + user.get ('name'));
console.log ('age: ' + user.get ('age'));
Ext.each (user.get ('skills'), function (skill) {
console.log ('*** SKILL ***');
console.log (skill);
console.log ('type: ' + skill.type);
console.log ('level: ' + skill.skillLevel);
console.log ('*** LEVELS ***');
Ext.each (skill.levels, function (level) {
console.log (level);
});
});
});
Here's a jsfiddle to test this last one: jsfiddle
I hope to have understood what you requested. If I didn't, please let me know with an example made by yourself ;)
I have this json which populates my collection (TableListCollection) of models (TableModel)
{
"tables": [
{
"tableId": 15,
"size": 8,
"occupiedSeats": 0,
"stakes": {
"smallBlindAmount": 10,
"bigBlindAmount": 20,
"minBuyInAmount": 20,
"maxBuyInAmount": 200
},
"gameType": "HOLDEM",
"gameSpeed": "NORMAL",
"friends": []
},
{
"tableId": 16,
"size": 8,
"occupiedSeats": 0,
"stakes": {
"smallBlindAmount": 20,
"bigBlindAmount": 40,
"minBuyInAmount": 20,
"maxBuyInAmount": 200
},
"gameType": "HOLDEM",
"gameSpeed": "NORMAL",
"friends": []
},
{
"tableId": 17,
"size": 8,
"occupiedSeats": 0,
"stakes": {
"smallBlindAmount": 40,
"bigBlindAmount": 60,
"minBuyInAmount": 20,
"maxBuyInAmount": 200
},
"gameType": "HOLDEM",
"gameSpeed": "NORMAL",
"friends": []
}
]
}
I want to find the table with the minimum smallBlindAmount.
I see that I can use the _.min() but I can't figure out what I have to pass as an iterator.
Thanks in advance.
Either directly on the JSON
var json=...
var min = _.min(json.tables,function(item) {
return item.stakes.smallBlindAmount
});
console.log(min.stakes.smallBlindAmount);
or on your collection
var json=...
var c=new Backbone.Collection(json.tables);
var m=c.min(function(model) {
return model.get("stakes").smallBlindAmount
});
console.log(m.get("stakes").smallBlindAmount);
In both cases, the iterator is used to extract the values to be compared.