Complete a function that takes in three parameters, an object, and a string (which will represent a key), and a value. The function needs to add a property to the inputted object. The property's key is a string, and the value of this property should be the inputted value. The function should return the inputted object.
function addProperty(obj, key, value) {
// your code here
var obj = {};
obj[key] = value;
return obj;
}
As this function stands it takes in one key and one value. I need it to let me add as many keys and values as I want. Please help.
1) Passing array of key and value
function addProperty(obj, keyArr, valueArr) {
keyArr.forEach((k, i) => {
obj[k] = valueArr[i];
});
return obj;
}
const keys = ["A", "B", "C"];
const values = ["value of A", "value of A", "value of A"];
let obj = {};
obj = addProperty(obj, keys, values);
console.log(obj);
2) Iterating over array key and calling the function as many times as length of the key array
function addProperty(obj, key, value) {
obj[key] = value;
return obj;
}
const keys = ["A", "B", "C"];
const values = ["value of A", "value of A", "value of A"];
let obj = {};
keys.forEach((k, i) => {
obj = addProperty(obj, k, values[i]);
});
console.log(obj);
try this
function addProperty(obj, keys_and_values) {
// your code here
var obj = {}
for (let key in keys_and_values) {
obj[key] = keys_and_values[key]
}
return obj
}
console.log(addProperty({}, {"name": "hi", "age": 69}))
output
{
age: 69,
name: "hi"
}
You'll have to remove var obj = {} in your addProperty function. I think you want to pass the object which should be expanded, right?
var obj = {};
var data = [{
key: "KEYA",
value: "VALUEA"
},
{
key: "KEYB",
value: "VALUEB"
}
];
var data2 = [{
key: "KEYC",
value: "VALUEC"
}
];
//Add key/value pairs to obj
console.log(addProperty(obj, data));
//Add another key/value pair to obj
console.log(addProperty(obj, data2));
function addProperty(obj, data) {
for (var key in data) {
obj[data[key].key] = data[key].value;
}
return obj;
}
I don't know why everyone were over explaining the question here-
We need to achieve 3 things here-
Function needs to add a property to the inputted object.
The value of property should be the inputted value.
function should return the inputted object.
function addProperty(obj, key, value) {
obj[key] = value ;
return obj ;
}
Related
I found this JavaScript code for copying Objects, the code is doing what it's suppose to do, but what I don't understand is when the function call itself; how come newObject in the first iteration desn't loose its value, it should be overwritten when the function called itself and created a new newObject ? does that mean that when a function call itself it still keeps a copy of the first newObject created before it called itself?
const o = {
a: 'a',
b: 'b',
obj: {
key: 'key',
},
}
const o2 = o
o2.a = 'new value'
// o and o2 reference the same object
console.log(o.a)
// this shallow-copies o into o3
const o3 = Object.assign({}, o)
// deep copy
function deepCopy(obj) {
// check if vals are objects
// if so, copy that object (deep copy)
// else return the value
const keys = Object.keys(obj)
const newObject = {}
for (let i = 0; i < keys.length; i++) {
const key = keys[i]
if (typeof obj[key] === 'object') {
newObject[key] = deepCopy(obj[key])
} else {
newObject[key] = obj[key]
}
}
return newObject
}
const o4 = deepCopy(o)
o.obj.key = 'new key!'
console.log(o4.obj.key)
Recursive functions can be confusing. A few well placed console.log()s or running the code in a debugger can really help. The function makes a newObject for the original object and each child object in the object. As the recursion unwinds it sets the property in the parent to the result of the recursive call on the child.
You can see the effect in the console.logs here:
const o = {
a: 'a',
b: 'b',
obj: {
key: 'key',
deeper: {one: 1, two: 2}
},
}
// deep copy
function deepCopy(obj) {
console.log("deep copy of: ", obj)
const keys = Object.keys(obj)
const newObject = {}
for (let i = 0; i < keys.length; i++) {
const key = keys[i]
if (typeof obj[key] === 'object') {
console.log("setting child of", key, "to:")
newObject[key] = deepCopy(obj[key])
} else {
newObject[key] = obj[key]
}
}
return newObject
}
console.log("starting with")
const o4 = deepCopy(o)
Each of the lines starting with deep copy of indicates a newly created newObject in a recursive call, but the only newObject returned is the first one — all the others get set as children.
How to assign the value to array in object value? It may has multiple input coming in and expected the input appended to array.
Code:
var ob = {};
$.each( input, function( key, value ) {
var v = [];
ob[key] = v.push(value);
console.log( v );
console.log( "obj: " + ob );
console.log( key + ": " + value );
});
Input:
First input- {A: "34",B: "2"}
Second input- {A: "21",B: "11"}
Expected:
ob = {A: ["34","21"] ,B: ["2","11"]}
Hope this helps,
var ob = {};
$.each(input, function(key, value) {
if (!ob[key]) {
ob[key] = []; // Creates a new Array for the key, if no array is there
}
ob[key].push(value); // Pushes the value to the array of the particular key
});
Create a function and an object variable. Check if the key exist in that object. If it does not exist they create the key and push the values
let input1 = {
A: "34",
B: "2"
}
let input2 = {
A: "21",
B: "11"
}
// a object which will hold the key and value
let finalObj = {};
// create a function which will be called o add key an value property to object
function createObj(obj) {
// iterate the object
for (let keys in obj) {
// check if final object has the relevent key
if (finalObj.hasOwnProperty(keys)) {
// if it has that key then push the value according to the key
finalObj[keys].push(obj[keys])
} else {
finalObj[keys] = [obj[keys]]
}
}
}
createObj(input1)
createObj(input2)
console.log(finalObj)
The problem is v empties on each iteration, because of this line:
var v = [];
Try doing this instead:
$.each(input, (key, val) => {
if (ob[key]) {
ob[key].push(val);
} else {
ob[key] = [val];
}
});
I have weird object:
{"Cats":10,"Dogs":815,"Fishes":2}
How can I get full value from each piece of data
var t = {"Cats":10,"Dogs":815,"Fishes":2};
var keys = [];
for (var key in t) {
if (t.hasOwnProperty(key)) {
console.log(key)
}
}
I'm getting only the names without number
I can use JSON.stringify and then manipulate that object but maybe there is other way?
Probably I missing something?
the for...in statement iterate over the property names get the value by property name.
var t = {"Cats":10,"Dogs":815,"Fishes":2};
var keys = [];
for (var key in t) {
if (t.hasOwnProperty(key)) {
console.log(key, t[key])
}
}
If you would like to generate an array of values then use Object.keys and Array#map methods.
var t = { "Cats": 10, "Dogs": 815, "Fishes": 2};
var keys = Object.keys(t);
var values = keys.map(function(key) {
return t[key];
});
console.log(keys, values);
var t = {"Cats":10,"Dogs":815,"Fishes":2};
var keys = [];
for (var key in t) {
if (t.hasOwnProperty(key)) {
console.log(key, t[key])
}
}
You could get the own properties first with Object.keys and iterate then.
var t = { Cats: 10, Dogs: 815, Fishes: 2 },
keys = Object.keys(t);
keys.forEach(function (key) {
console.log(key, t[key]);
});
var t = {"Cats":10,"Dogs":815,"Fishes":2};
for (var key in t)
{
console.log(key, t[key]);
}
I have several objects like this:
{'id[0]': 2}
{'url[0]': 11}
{'id[1]': 3}
{'url[1]': 14}
And I want to get something like this:
[{id:2, url:11}, {id:3, url:14}]
Also I have lodash in my project. Maybe lodash have some method for this?
You could use a regular expression for the keys and create a new object if necessary. Then assign the value to the key.
var data = [{ 'id[0]': 2 }, { 'url[0]': 11 }, { 'id[1]': 3 }, { 'url[1]': 14 }],
result = [];
data.forEach(function (a) {
Object.keys(a).forEach(function (k) {
var keys = k.match(/^([^\[]+)\[(\d+)\]$/);
if (keys.length === 3) {
result[keys[2]] = result[keys[2]] || {};
result[keys[2]][keys[1]] = a[k];
}
});
});
console.log(result);
This is an ES6 solution based on #NinaScholz solution.
I assume that the objects have only one property each, like the ones presented in the question.
Combine the array of objects to one large object using Object#assign, and convert to entries with Object.entries.
Iterate the array using Array#reduce.
Extract the original key an value from each entry using array
destructuring.
Extract the wanted key and index using a regex and array
destructuring.
Then create/update the new object at the index using object spread.
const data = [{ 'id[0]': 2 }, { 'url[0]': 11 }, { 'id[1]': 3 }, { 'url[1]': 14 }];
// combine to one object, and convert to entries
const result = Object.entries(Object.assign({}, ...data))
// extract the original key and value
.reduce((r, [k, value]) => {
// extract the key and index while ignoring the full match
const [, key, index] = k.match(/^([^\[]+)\[(\d+)\]$/);
// create/update the object at the index
r[index] = {...(r[index] || {}), [key]: value };
return r;
}, []);
console.log(result);
var arr = [{'id[0]': 2},
{'url[0]': 11},
{'id[1]': 3},
{'url[1]': 14}];
var result = [];
arr.forEach(function(e, i, a){
var index = +Object.keys(e)[0].split('[')[1].split(']')[0];//get the number inside []
result[index] = result[index] || {}; //if item is undefined make it empty object
result[index][Object.keys(e)[0].split('[')[0]] = e[Object.keys(e)[0]];//add item to object
})
console.log(result);
You can use for loop, .filter(), RegExp constructor with parameter "\["+i+"\]" where i is current index, Object.keys(), .reduce(), .replace() with RegExp /\[\d+\]/
var obj = [{
"id[0]": 2
}, {
"url[0]": 11
}, {
"id[1]": 3
}, {
"url[1]": 14
}];
var res = [];
for (var i = 0; i < obj.length / 2; i++) {
res[i] = obj.filter(function(o) {
return new RegExp("\[" + i + "\]").test(Object.keys(o))
})
.reduce(function(obj, o) {
var key = Object.keys(o).pop();
obj[key.replace(/\[\d+\]/, "")] = o[key];
return obj
}, {})
}
console.log(res);
I have an object like this:
var data = {"prop.health": 1, "prop.cost":1, "prop.time":1}
I want to change it into an object like this:
{
"prop": {
"health": 1,
"cost":1,
"time":1
}
}
Here's my code:
_.each(data, function (value, key) {
var split = key.split('.')
if (split.length > 1) {
data[split[0]] = data[split[0]] || {}
data[split[0]][split[1]] = value
delete data[key]
}
})
But this only works for 1 level of nesting. How would you write it to ensure it works for as deeply nested properties as you need?
You can use a combination of _.transform and _.set, for example
data = _.transform(data, function(transformed, val, key) {
_.set(transformed, key, val);
});
Results in
{"prop":{"health":1,"cost":1,"time":1}}
Without a library it would be something like this:
(function(){
var data = {"prop.health": 1, "prop.cost":1, "prop.time":1, "prop.test.fun" : 1, "prop.test.sun" : 1};
var obj = {}; //will hold the object all parsed out
Object.keys(data).forEach( function (key) { //loop through the keys in the object
var val = data[key]; //grab the value of this key
var step = obj; //reference the object that holds the values
key.split(".").forEach(function(part, index, arr){ //split the parts and loop
if(index===arr.length-1){ //If we are at the last index, than we set the value
step[part] = val;
} else if(step[part]===undefined) { //If we have not seen this key before, create an object
step[part] = {};
}
step = step[part]; //Step up the object we are referencing
});
} );
console.log(obj);
}());
Or the double reduce loop
(function(){
var data = {"prop.health": 1, "prop.cost":1, "prop.time":1, "prop.test.fun" : 1, "prop.test.sun" : 1};
var result = Object.keys(data).reduce( function (obj, key) { //loop through the keys in the object
var val = data[key]; //grab the value of this key
key.split(".").reduce(function(step, part, index, arr){ //split the parts and loop
if(index===arr.length-1){ //If we are at the last index, than we set the value
step[part] = val;
} else if(step[part]===undefined) { //If we have not seen this key before, create an object
step[part] = {};
}
return step[part]; //Step up the object we are referencing
}, obj);
return obj;
}, {});
console.log(result);
}());
Depending on a number of factors (e.g. if the original object always has keys you want to delete, etc.) you may be able to use _.set:
var data = {"prop.health": 1, "prop.cost":1, "prop.time":1};
_.each(data, function (value, key) {
delete data[key];
_.set(data, key, value);
});
_.set will create the path if it doesn't exist. The above results in:
{"prop":{"health":1,"cost":1,"time":1}}
And {"prop.health": 1, "prop.cost.food":1, "prop.time":1} will result in:
{"prop":{"health":1,"cost":{"food":1},"time":1}}