Can you help me to solve this problem?
export class SomePage {
reg = [{apple: 201, ball: 21, cat: 12}, {apple: 202, ball: 65, cat: 15}];
constructor() {
firebase.database().ref('app/test').set({
// i want to set all ***cat*** values here like:
// key1: 12
// key2: 15
})
.
Tried to extract cat values with this method:
let keys = this.reg.map(a => a.cat);
console.log(keys); // <unavailable>
You have your reg array of objects.
Initialize the resultObject
Create a counter to increment the key of resultObject
Filter all cat values from reg array and set it to resultObject.
Update it in your firebase db.
//1
var reg = [{apple: 201, ball: 21, cat: 12}, {apple: 202, ball: 65, cat: 15}];
//2
var resultObject = {};
//3
var count = 0;
//4
reg.filter(function(elem){ resultObject['key'+ ++count] = elem.cat});
//5
constructor() {
firebase.database().ref('app/test').set(resultObject);
}
Figured out a solution:
this.reg.map(a => {
let first = a.ball; // or add any key
let addORupdate = {};
addORupdate[first] = a.cat; // expected value from array
firebase.database().ref('app/test').update(addORupdate);
// this will add 21:12 and 65:15 under the parent "test"
});
Related
I am trying to push data into a variable Data[] but all I have is an example of how to do this hard coded:
var data = [{
id: "1",
name: "Development Life Cycle",
actualStart: Date.UTC(2018, 01, 02),
actualEnd: Date.UTC(2018, 06, 15),
children: [{
id: "1_1",
name: "Planning",
actualStart: Date.UTC(2018, 01, 02),
actualEnd: Date.UTC(2018, 01, 22),
connectTo: "1_2",
connectorType: "finish-start",
progressValue: "75%"
},
// more data goes here
]
}];
I tried with following code but it doesn't seem to work:
ganttdata = [];
// DUMMY DATA
id = 10;
RFInum = 'asfd';
start= 1;
LTIOV = 2;
progressValue = 10;
ganttdata.push("{id:"+id, "parent: null", "name:"+RFInum, "actualStart: Date.UTC("+start+")", "actualEnd: Date.UTC("+LTIOV+")", "progressValue:"+progressValue+"%}");
console.log(ganttdata);
Anyone know how to write this?
You are currently inserting your data as a string and not as an object.
I recreated your approach and inserted your data as an object into the ganttdata array.
Date documentation
var ganttdata = [];
// DUMMY DATA
var id = 10;
var RFInum = 'asfd';
var start = Date.UTC(2021, 12, 31);
var LTIOV = Date.UTC(2021, 12, 31);
var progressValue = 10;
ganttdata.push({
id,
parent: null,
name: RFInum,
actualStart: start,
actualEnd: LTIOV,
progressValue: `${progressValue}%`,
});
console.log(ganttdata);
Or if you want to append some data to an existing object at a specific index:
var data = [{
id: 1,
name: 'test'
}];
console.log('before:', data);
data[0].extend = 'hello World';
data[0].foo = 'bar';
console.log('after:', data);
I want to concat 2 objects into the first object, but making sure the array elements stay in the same x-positions, like:
object.name[x],
object.age[x].
Also, I don't want any duplicates to be overwritten. Every entry should be preserved.
var users = {
name : [joe , tim],
age : [20 , 21]
}
var usersTemp = {
name : [bob , joe],
age : [22 , 23]
}
Result should be saved into (expand) the existing 'users' object:
var users = {
name : [joe , tim , bob , joe],
age : [20 , 21 , 22 , 23 ]
}
PS: I'm new to javascript, and since I cant find any examples I am wondering if this approach even makes sense? The list is SUPER long (over 50k entries).
You can use Array Destructuring to achieve this task if you don't want to append in the original array.
var users = {
name: ["joe", "tim"],
age: [20, 21],
};
var usersTemp = {
name: ["bob", "joe"],
age: [22, 23],
};
const result = {
name: [...users.name, ...usersTemp.name],
age: [...users.age, ...usersTemp.age],
};
console.log(result);
If you want to add in the same array then assign the result in the same variable users
var users = {
name: ["joe", "tim"],
age: [20, 21],
};
var usersTemp = {
name: ["bob", "joe"],
age: [22, 23],
};
users = {
name: [...users.name, ...usersTemp.name],
age: [...users.age, ...usersTemp.age],
};
console.log(users);
If there are multiple properties in both object that need to merge
var users = {
name: ["joe", "tim"],
age: [20, 21],
};
var usersTemp = {
name: ["bob", "joe"],
age: [22, 23],
};
for (let key in users) {
users[key].push(...usersTemp[key]);
}
console.log(users);
You could make a function that takes two objects with arbitrary keys and builds your new object with the concatenated values. You can then grab the entries of one of your objects using Object.entries(), which will give you a [[key, value], ...] pair array representation of your object:
[
['name', ['joe', 'tim']], // <- inner key-value pair array
['age', [20, 21]]
]
Using this array, you can then use the .map() method on it, to convert each inner key-value pair into a new key-value pair array, where the key remains, but the value is a concatenated version of the current array value with its corresponding array value from the other object you want to merge with. Once you have your modified the entries array, you can use Object.fromEntries() on this array to build your new object from the entries array:
const users = { name: ['joe', 'tim'], age: [20, 21] };
const usersTemp = { name: ['bob', 'ted'], age: [22, 23] };
function concatObjVals(obj1, obj2) {
return Object.fromEntries(
Object.entries(obj1).map(([key, arr]) => [
key,
arr.concat(obj2[key])
])
);
}
console.log(concatObjVals(users, usersTemp));
This could be written in a more concise manner if you use arrow-functions:
const concatObjVals = (obj1, obj2) =>
Object.fromEntries(Object.entries(obj1).map(([key, arr]) => [key, arr.concat(obj2[key])]));
If you find it easier to understand, you can use a regular for..in loop instead of Object.entries() and .map() to build your new object. The below for..in loop will iterate through all the keys in your first object (ie: users), and add that key to a new object result. It will also set the value to be the current value of the key from the first object, concatenated with the array value from the second object for the current key:
const users = { name: ['joe', 'tim'], age: [20, 21] };
const usersTemp = { name: ['bob', 'ted'], age: [22, 23] };
function concatObjVals(obj1, obj2) {
const result = {};
for(const key in obj1) {
result[key] = obj1[key].concat(obj2[key]);
}
return result;
}
console.log(concatObjVals(users, usersTemp));
var users = {
name : ['joe' , 'tim'],
age : [20 , 21]
}
var usersTemp = {
name : ['bob' , 'joe'],
age : [22 , 23]
}
usersTemp.name.push(...users.name)
usersTemp.age.push(...users.age)
console.log(usersTemp)
// output
// { name: Array ["bob", "joe", "joe", "tim"], age: Array [22, 23, 20, 21] }
In javascript, is there a way to treat a JSON keyname as a variable?
For instance, below I want to perform (any set of actions) on the value of a different key in JSON each time, by telling it which json key to get by feeding the keyname to the function as a parameter.
The basic idea here is: Make a function to do (x) no matter what JSON it's given. I just need to tell it what key I want.
var myObj = {name: "John", age: 31}; // dataset #1
var myObj2 = {month: "January", day: 20}; //dataset #2
function myFunction(jsonName, variableKeyName) {
var variableKeyValue = jsonName + "." + variableKeyName; //wrong way to do this, apparently.
console.log(variableKeyValue);
}
myFunction("myObj", "name"); //want this to log "John", not the string "myObj.name".
myFunction("myObj2", "day"); //want this to log "20", not the string "myObj2.day".
Is this possible? How do get the function to assign the VALUE of the string I'm building with the parameter, rather than just the string as "jsonNameX.variableKeyNameX"?
const myObj = {name: "John", age: 31}; // dataset #1
const myObj2 = {month: "January", day: 20}; //dataset #2
function myFunction(json, variableKeyName) {
const variableKeyValue = json[variableKeyName];
console.log(variableKeyValue);
}
myFunction(myObj, "name"); // this log "John"
myFunction(myObj2, "day"); // this log 20
or you can access to global context using "this" keyword and variable name (instead variable identifier == reference)
const myObj = {name: "John", age: 31}; // dataset #1
const myObj2 = {month: "January", day: 20}; //dataset #2
function myFunction(jsonName, variableKeyName) {
const variableKeyValue = this[jsonName][variableKeyName];
console.log(variableKeyValue);
}
myFunction("myObj", "name"); // this log "John"
myFunction("myObj2", "day"); // this log 20
Yes you can do it. You can get the JSON value like this:
jsonName.variableKeyName;
but you can also get it like this:
jsonName["variableKeyName"];
(https://www.w3schools.com/js/js_json_syntax.asp)
So you can change your code in this way:
var myObj = {name: "John", age: 31}; // dataset #1
var myObj2 = {month: "January", day: 20}; //dataset #2
function myFunction(jsonName, variableKeyName) {
var variableKeyValue = jsonName[variableKeyName];
console.log(variableKeyValue );
}
myFunction(myObj, "name"); //this prints "John"
myFunction(myObj2, "day"); //this prints "20"
I have an array of objects with named keys as follows:
Array [
{
'postal1': 111, // number
'postal2': 222, // number
'town': 'London', // string
},
{},{},... // Objects with same properties
]
The array is created after DOM and populated dynamically from a backend, so from the very beginning it's just an empty array.
Having all this I want to create a new object where keys will be town and their values will be an array of two other keys postal1 and postal2.
Object {
'London': [111,222],
'town...': [rand,rand],
}
How one could make it in the most efficient way?
You can use Array.reduce() to generate an object from the array:
const data = [{
'postal1': 111, // number
'postal2': 222, // number
'town': 'London', // string
}];
const result = data
.reduce((r, { town, postal1, postal2 }) => {
r[town] = [postal1, postal2];
return r;
}, {});
console.log(result);
Try this:
var A= [
{
'postal1': 1110, // number
'postal2': 2220, // number
'town': 'A', // string
},
{
'postal1': 1111, // number
'postal2': 2221, // number
'town': 'B', // string
},
{
'postal1': 1112, // number
'postal2': 2222, // number
'town': 'C', // string
}
];
var desiredResult={};
A.forEach(function(a){
desiredResult[a.town]=[a.postal1, a.postal2];
});
console.log(desiredResult);
But this is faster than all:
var i=0,
result={};
for(; i<A.length; i++) result[A[i].town]=[A[i].postal1, A[i].postal2];
I have the following code:
var gameController = {
scores: [20, 34, 55, 46, 77],
avgScore: 112,
players: [
{name: "Ruth", playerId: 100, age: 22},
{name: "Shawnee", playerId: 101, age: 21}
]
};
var appController = {
scores: [900, 845, 809, 950],
avgScore: null,
avg: function () {
var sumOfScores = this.scores.reduce(function (prev, cur, index, array) {
return prev + cur;
});
this.avgScore = sumOfScores / this.scores.length;
}
};
gameController.avgScore = appController.avg();
console.log(gameController.avgScore);
I tried to borrow the avg method defined in appController to do the calculation for gameController. I understand that after gameController.avgScore = appController.avg();, this keyword in avg method will still point to appController as avg method was invoked by appController so I expect avgScore in gameController should remain intact, but the output is undefined, why?
avg doesn't return anything, so it implicitly returns undefined. You are basically doing gameController.avgScore = undefined;.
If you want to apply the avg method to gameController, you could use .call:
appController.avg.call(gameController);
Better would probably be to have avg as a standalone function that accepts an array of numbers as input (argument) and returns the average.
Updated:
When assigning a function to an object the this keyword is set to the object when the function is invoked. This is true only for unbound function references. If the function reference is bound to another object you will have to use the Function.bind() method to ensure this is set to the correct object.
Answer
Rather than use call each time just assign the function to the object. When the function is call the this is set to the object
gameController.avg = appController.avg; // unbound function reference.
// now when you need to get the average for gameController
// just call its avg function
gameController.avg(); // this is automatically set to gameControler
Better still create the function outside the controllers and assign them at creation time.
// define the avg and refer it to the unbound function that you will share
var avg = function () {
var sumOfScores = this.scores.reduce(function (prev, cur, index, array) {
return prev + cur;
});
this.avgScore = sumOfScores / this.scores.length;
console.log(this.avgScore);
}
// create the objects as normal
var gameController = {
scores: [20, 34, 55, 46, 77],
avgScore: 112,
players: [
{name: "Ruth", playerId: 100, age: 22},
{name: "Shawnee", playerId: 101, age: 21}
],
avg:avg // avg is automatically bound to gameController when it is called
};
var appController = {
scores: [900, 845, 809, 950],
avgScore: null,
avg:avg // avg is automatically bound to appController when it is called
};
// or if you want to get really lazy.
var otherController = {
scores: [900, 900, 900, 900],
avgScore: null,
avg // avg is automatically bound to otherController when it is called
// and it is automatically named avg as well
};
appController.avg(); // 46.4
gameController.avg(); // 876
otherController.avg(); // 900
And there are over half a dozen other ways to achieve the same thing.