Assign an object property value to another property while declaring the object - javascript

I have the following Javascript code:
var container = {
first: {
a: 1,
b: 'someString'
},
second: Object.assign({
c: 34,
d: 'something else'
},
this.first
)
}
console.log(container)
This prints:
{ first: { a: 1, b: 'someString' },
second: { c: 34, d: 'something else' } }
However, I would like it to be:
{ first: { a: 1, b: 'someString' },
second: { c: 34, d: 'something else', a: 1, b: 'someString'} }
So I would like all the (key, value) pairs from first to also be present in second. How can that be done?

You can't refer to an object before it exists, which is what you're trying to do. But you can do this:
var first = {
a: 1,
b: 'someString'
};
var container = {
first: first,
second: Object.assign({
c: 34,
d: 'something else'
},
first
)
}
console.log(container)

Problem:
In fact you are assigning the content of second with undefined, because at the time you are trying to refer the first property, at the assignement time, it doesn't exist yet in your container object.
Solution:
You need either to store the content of first property in an object before the assignement or create your container object with only first property and then define container.second property to get first value combined with second value.
This is how can be your code:
var container = {
first: {
a: 1,
b: 'someString'
}
};
container.second = Object.assign({
c: 34,
d: 'something else'
},
container.first
);
console.log(container)

You may looking for this.
var a = new function(){
this.b = {name:"Vignesh",place:"India"};
this.c = {name:"Vijay",place:"TamilNadu",b:this.b};
this.d = {name:"Vijay Sethupathi",place:"Namakkal",c:this.c};
}();
console.log(a);

var container = {
first: {
a: 1,
b: 'someString'
}
}
container.second = Object.assign(
{
c: 34,
d: 'Something else'
},
container.first
)

Related

js common function which calculates and assign to object values?

Example of what i'm trying to achieve
I want to make an object in react which will calculate one its key value from other keys using this function and the 'this' keyword so that I can use this function dynamically with many input fields object.
func = function (c) {
return this.a + this.b + c;
};
obj1 = {
a: 1,
b: 2,
value: func(5),
};
obj2 = [
{ a: 2, b: 3, value: func(6) },
{
a: 4,
b: 5,
value: func(7),
},
];
// expected result
console.log(obj1.value); // 8
console.log(obj2[0].value); // 16
I guess the simplest solution would to flip this around: Pass the object to the function, let it add the property and return the very same object:
const func = function (obj, c) {
obj.value = obj.a + obj.b + c;
return obj;
};
const obj1 = func({
a: 1,
b: 2,
}, 5);
const obj2 = [
func({ a: 2, b: 3 }, 6),
func({
a: 4,
b: 5,
}, 7),
];
// expected result
console.log(obj1.value); // 8
console.log(obj2[0].value); // 16
(no idea how the second example would result in 16 though)
At the moment func is called, this is set to window object, because the object you want to use it in, doesn't exist yet.
You can try returning a function from func
const func = function(c) {
return function() {
return this.a + this.b + c
}
}
const obj1 = {
a: 1,
b: 2,
value: func(5),
}
const obj2 = [{
a: 2,
b: 3,
value: func(6)
},
{
a: 4,
b: 5,
value: func(7)
}
]
// expected result
console.log(obj1.value()) // 8
console.log(obj2[0].value()) // 11

Jest failing one function but not another

I am writing some daily challenges for my coding bootcamp and I am running into an issue on one problem. I wrote a function that combines objects and it works correctly. Here is what the problem prompt is
Prompt: Write a function named mergeObjects that accepts at least two objects as arguments, merges the properties of the second through n objects into the first object, then finally returns the first object. If any objects have the same property key, values from the object(s) later in the arguments list should overwrite earlier values.
Examples:
mergeObjects({}, {a: 1}); //=> {a: 1} (same object as first arg)
mergeObjects({a: 1, b: 2, c: 3}, {d: 4}); //=> {a: 1, b: 2, c: 3, d: 4}
mergeObjects({a: 1, b: 2, c: 3}, {d: 4}, {b: 22, d: 44}); //=> {a: 1, b: 22, c: 3, d: 44
My function
function mergeObjects(...obj) {
let obj1 = {}
obj.forEach(element => {
obj1 = {...obj1, ...element}
});
return obj1
}
Solution function
function mergeObjects1(target, ...objects) {
objects.forEach(function (obj) {
// using ES2015's 'for in' loop
for (var key in obj) {
target[key] = obj[key]
}
})
return target
}
In my eyes these two functions provide the same result. However, when I run my code through the jest test they created it fails on the first test. But the solution they provide, does not fail. The jest test is below.
describe('15-mergeObjects', function () {
it('returns same object', function () {
var obj = {}
expect(mergeObjects(obj, { a: 1 })).toBe(obj)
})
it('adds additional properties', function () {
expect(mergeObjects({ a: 1, b: 2, c: 3 }, { d: 4 })).toEqual({
a: 1,
b: 2,
c: 3,
d: 4
})
})
it('merges props from left to right', function () {
expect(
mergeObjects({ a: 1, b: 2, c: 3 }, { d: 4 }, { b: 22, d: 44 })
).toEqual({ a: 1, b: 22, c: 3, d: 44 })
})
})
describe('15-mergeObjects', function () {
it('returns same object', function () {
var obj = {}
expect(mergeObjects1(obj, { a: 1 })).toBe(obj)
})
it('adds additional properties', function () {
expect(mergeObjects1({ a: 1, b: 2, c: 3 }, { d: 4 })).toEqual({
a: 1,
b: 2,
c: 3,
d: 4
})
})
it('merges props from left to right', function () {
expect(
mergeObjects1({ a: 1, b: 2, c: 3 }, { d: 4 }, { b: 22, d: 44 })
).toEqual({ a: 1, b: 22, c: 3, d: 44 })
})
})
Can anyone provide an explanation as to why the solution function passes while my function does not?
While the results look the same, the two functions are slightly different.
In your function, you are creating a new object and then adding to it all of the required properties.
In the solution function, they are adding properties to the original target object and then returning it.
The returned objects from both functions will have the same keys and the same values, but different references, so they are not considered the same object in JavaScript.
In the test
expect(mergeObjects1(obj, { a: 1 })).toBe(obj)
.toBe() checks whether two objects are the same (identity), therefore it fails the case of your function.
Note that there is a different test, .toEqual(), which checks whether two objects have the same keys and the same values (but possibly different references). Your function would pass this test
expect(mergeObjects1(obj, { a: 1 })).toEqual(obj)

How to sum two similar Objects in Javascript / vuejs

I have an object and I need to sum every value independently with another similar object like in this example :
CharacterStats: { a: 0, b: 2, c: 0, d: 0 }
ItemStats: { a: 0, b: -1, c: 4, d: 0 }
The Result should be
CharacterStats: { a: 0, b: 1, c: 4, d: 0 }
I found this answer How to sum two object values in javascript But I'm using vueJS so my function looks something like this:
export default {
data () {
return {
CharacterStats: { a:0, b:0, c:0, d:0 }
};
},
methods: {
calculStatsItems(ItemsStats) {
var obj = {};
Object.keys(this.CharacterStats ).forEach(function(a){
obj[a] = this.CharacterStats.stat[a] +ItemsStats[a]
})
console.log(obj);
}
},
}
But i keep getting an error telling me "this is undifined" on this line:
Object.keys(this.CharacterStats ).forEach(function(a)
Is there another way to do it or fix it?
You can get the values of both objects, and then make the operation, doing something like:
sum(values) {
return values.reduce((a, b) => a + b, 0);
}
calculStatsItems(arr1, arr2) {
const prepareData = [...Object.values(arr1), ...Object.values(arr2)];
return this.sum(prepareData);
}
In the .forEach function, this doesn't refer to the vue component instance, so CharacterStats becomes undefined. Try this:
const CharacterStats = { a: 0, b: 2, c: 0, d: 0 };
const ItemStats = { a: 0, b: -1, c: 4, d: 0 };
new Vue({
el:"#app",
data: () => ({
CharacterStats: { a: 0, b: 2, c: 0, d: 0 }
}),
created() {
this.calculStatsItems({ a: 0, b: -1, c: 4, d: 0 });
},
methods: {
calculStatsItems(ItemsStats) {
const obj = {};
Object.keys(this.CharacterStats).forEach(a => {
obj[a] = this.CharacterStats[a] + (ItemsStats[a] || 0)
});
console.log(obj);
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app"></div>

Get an element object of an array from a key name

I'm parsing a csv fils to json with node-csvtojson and I got a JSONarray with the following code
csv({delimiter: ';'}).fromFile(path).then((jsonObj)=>{
data = jsonObj;
console.log(jsonObj);
})
with a csv like
a,b,c
A,B,C
1,2,3
1,B,C
I have got
[
{
a: A,
b: B,
c: C,
},
{
a: 1,
b: 2,
c: 3,
},
{
a: 1,
b: B,
c: C
}
]
But I want to find every object who has the element a === 1 and I want to have all the content of the object,
like this:
{
a: 1,
b: 2,
c: 3,
},
{
a: 1,
b: B,
c: C,
}
But I 'm struggling to do that, I have tried with array.filter but without success then I have tried to do this with array.map but I got lost on how to do.
Do you have any idea on or I could do that ?
Than you
Use Array.filter like so:
const data = [{
a: 'A',
b: 'B',
c: 'C',
},
{
a: 1,
b: 2,
c: 3,
},
{
a: 1,
b: 'B',
c: 'C'
}
];
console.log(data.filter(({ a }) => a == 1));
If you want this to work with old browsers, here's an ES5-compliant version:
var data = [{
a: 'A',
b: 'B',
c: 'C',
},
{
a: 1,
b: 2,
c: 3,
},
{
a: 1,
b: 'B',
c: 'C'
}
];
console.log(data.filter(function(obj) {
return obj.a == 1
}));
Simple use Array.filter to filter through the object array and select the one having property a === 1
var arr = [{"a":"A","b":"B","c":"C"},{"a":1,"b":2,"c":3},{"a":1,"b":"B","c":"C"}];
const filteredArr = arr.filter(obj => obj.a === 1);
console.log(filteredArr);
Using Array.reduce you can do the same thing:
var arr = [{"a":"A","b":"B","c":"C"},{"a":1,"b":2,"c":3},{"a":1,"b":"B","c":"C"}];
const redArr = arr.reduce((acc, obj) => {
return acc = obj.a === 1 ? acc.concat(obj) : acc;
}, []);
console.log(redArr);
Using Array.map for this problem is not the right approach, although it is possible:
var arr = [{"a":"A","b":"B","c":"C"},{"a":1,"b":2,"c":3},{"a":1,"b":"B","c":"C"}];
const mapArr = arr.map(obj => obj.a === 1 ? obj : undefined).filter(obj => obj); //hack to remove undefined elements
console.log(mapArr);
console.log([{
a: 'A',
b: 'B',
c: 'C',
},
{
a: 1,
b: 2,
c: 3,
},
{
a: 1,
b: 'B',
c: 'C'
}
].filter(o => o.a === 1))
Try this :
var arr = [{"a":"A","b":"B","c":"C"},{"a":1,"b":2,"c":3},{"a":1,"b":"B","c":"C"}];
var res = arr.filter(obj => obj.a === 1);
console.log(res);

Node not logging deeper subobject

This may have been answered, but I did search.
In js file:
console.log({
a: 1,
b: { c: 1},
d: [{e:1},{f:1}],
g: [{h:[1,2,3]}]
});
This is what actually prints:
{ a: 1,
b: { c: 1 },
d: [ { e: 1 }, { f: 1 } ],
g: [ { h: [Object] } ]
}
Notice 'h' value, can I print this?
Read the docs for util.inspect()
It allows you to specify the depth to print at:
The default is to only recurse twice. To make it recurse indefinitely, pass in null for depth.
To use it, you could call console.log(util.inspect(yourObj, true, null));
console.dir() says it uses util.inspect(), but doesn't show parameters to modify the inspect() call, so it would probably only recurse twice, too.
You can use for loop to iterate over it..
var obj = {
a: 1,
b: {c: 1},
d: [{e: 1}, { f: 1}],
g: [{ h: [1, 2, 3]}]
};
var data = obj.g[0].h ;
for(var i =0; i <data.length ; i++){
console.log(data[i])
}​
Check Fiddle
I have used JSON.stringify() to achieve it, you can use parameters to determine the formatting.
As written above, util.inspect() also works.

Categories

Resources