How can i get both object length together from chain of object - javascript

Say I create a Object as follows
const myObj1 = {
firstName: "Shaheb",
lastName: "Ali",
professions:"Web Developer"
}
And create another object with the above object to add as a prototype object
const myObj2 = Object.create(myObj1, {
age:{
value:33
},
edu:{
value: "MBA"
}
});
now I want to count length of both object together, how can i?

I understand you want to get count of all keys in your object(s). As there is no length property available for objects (only for arrays), you should use Object.keys(), which returns an array with all keys:
const myObj1 = {
firstName: "Shaheb",
lastName: "Ali",
professions:"Web Developer"
}
Object.keys(myObj1).length; // would return '3'
I believe that instead of Object.create(), you actually want to use Object.assign(), which will assign all keys from myObj1 to myObj2:
const myObj1 = {
firstName: "Shaheb",
lastName: "Ali",
professions:"Web Developer"
}
const myObj2 = {
age:{
value:33
},
edu:{
value: "MBA"
}
}
Object.assign(myObj2, myObj1);
document.write(Object.keys(myObj2).length + '<br>'); // return '5'
document.write(Object.keys(myObj1).length); // return '3'

If I understand the OP goal:
const myObj1 = {
firstName: "Shaheb",
lastName: "Ali",
professions:"Web Developer"
}
const myObj2 = {
age:{
value:33
},
edu:{
value: "MBA"
}
};
const result = {...myObj1, ...myObj2};
console.log(result);
const length = Object.keys(result).length;
console.log(length);
{ firstName: 'Shaheb',
lastName: 'Ali',
professions: 'Web Developer',
age: { value: 33 },
edu: { value: 'MBA' }
}
5

const obj = Object.create(myObj1, myObj2);
create prototyping object looks like below
{age: 33, edu: "MBA"}
age: 33
edu: "MBA"
proto:
firstName: "Shaheb"
lastName: "Ali"
professions: "Web Developer"
proto: Object
but assigning a object is like a combining 2object into one. is this not possible to get the length from plan object and prototyping object together?
but your ans was awesome, help me a lot to make it better understand. if it is not possible then i will follow your suggestions.

Related

How to filter few properties of an object which is in Array of objects if one property equals property from another object

I have a object which has some properties for one user, and I have array of objects which is returned from API.
My goal is to check which object of Array of objects has the same property as the one single initial object, and then it should return only part of it's properities.
I have tried to use .map on Array of objects but it seems not workig.
Below is the code example. I have also prepared codesandbox if You wish.
const user =
{
name: "jan",
lastName: "kowalski",
fullName: "jan kowalski",
car: "audi"
}
;
const usersAnimal = [
{
name: "jan",
lastName: "kowalski",
fullName: "jan kowalski",
animal: "cat",
animalSize: "small",
animalName: "Bat"
},
{
name: "john",
lastName: "smith",
fullName: "john smith",
animal: "dog",
animalSize: "middle",
animalName: "Jerry"
},
{
name: "Anna",
lastName: "Nilsson",
fullName: "Anna Nilsson",
animal: "cow",
animalSize: "big",
animalName: "Dorrie"
}
];
const filtered = usersAnimal.map((userAnimal)=>userAnimal.fullName === user.fullName && return userAnimal.animalName & userAnimal.animalSize & userAnimal.animal);
thanks
https://codesandbox.io/s/admiring-edison-qxff42?file=/src/App.js
For case like this, it would be far easier if you filter it out first then proceed using map:
const filtered = usersAnimal
.filter((animal) => animal.fullName === user.fullName)
.map(({ animalName, animalSize, animal }) => {
return {
animalName,
animalSize,
animal
};
});
I am providing a for loop solution as I haven't learnt many array methods in javascript.
For me the simplest option is to use a for loop and an if check to loop through the arrays values to check for included values.
for (let v in usersAnimal) {
if (usersAnimal[v].fullName === user.fullName) {
console.log(usersAnimal[v])
}
}
The code above will log the entire usersAnimal object containing the fullname we are looking for.
{
name: 'jan',
lastName: 'kowalski',
fullName: 'jan kowalski',
animal: 'cat',
animalSize: 'small',
animalName: 'Bat'
}
commented for further understanding
for (let v in usersAnimal) {
//loops though the array
if (usersAnimal[v].fullName === user.fullName) {
//when the index value 'v' has a fullname that matches the user fullname value
// it passes the if check and logs that object value
return console.log(usersAnimal[v])
//return true...
}
//return null
}
//etc
If you want to filter, I recommend you to use filter.
The map method will create a new array, the content of which is the set of results returned by each element of the original array after the callback function is operated
const user = {name:"jan",lastName:"kowalski",fullName:"jan kowalski",car:"audi"};
const usersAnimal = [{name:"jan",lastName:"kowalski",fullName:"jan kowalski",animal:"cat",animalSize:"small",animalName:"Bat"},{name:"john",lastName:"smith",fullName:"john smith",animal:"dog",animalSize:"middle",animalName:"Jerry"}];
// Get an array of matching objects
let filtered =
usersAnimal.filter(o => o.fullName === user.fullName);
// You get the filtered array, then you can get the required properties
filtered.forEach(o => {
console.log(
'animal:%s, animalSize:%s, animalName:%s',
o?.animal, o?.animalSize, o?.animalName
);
});
// Then use map to process each element
filtered = filtered.map(o => {
const {animal, animalSize, animalName} = o;
return {animal, animalSize, animalName};
});
console.log('filtered', filtered);

Why getting "Destructuring expressions can only have identifier references" when trying to destruct an object?

I have the following object:
const john = {
family: [
{ firstName: 'david', secondName: 'jana' },
{ firstName: 'eyal', secondName: 'shani ' },
],
};
I want to get 'david' string in one operation. So i tried the following code:
const { family:[0]{firstName}}} = john;
But i'm getting the error :
"Destructuring expressions can only have identifier references"
Can someone tell me in simple words (cause i'm new in the language) what i'm doing wrong?
To extract a deeply nested value with destructuring, the syntax is nearly identical to when declaring an object with those properties. family:[0] isn't valid syntax - instead, you need to surround the contents of family in array delimiters:
const john = {
family: [{
firstName: 'david',
secondName: 'jana'
},
{
firstName: 'eyal',
secondName: 'shani '
},
],
};
const { family:[{firstName}]} = john;
console.log(firstName);
But I'd highly recommend against using nested destructuring like this. It's so hard to write and read and understand. Better to use plain dot notation at least for the outer accesses, eg
const john = {
family: [{
firstName: 'david',
secondName: 'jana'
},
{
firstName: 'eyal',
secondName: 'shani '
},
],
};
const { firstName } = john.family[0];
console.log(firstName);

Lodash merge object with nested array not working correctly

I found unexpected result when try to merge with lodash object with flat array inside.
Here the example:
var people = { name: 'Andrew', age: '30', values: ["PT", "PORTA 31"] };
const person = { age: '31', values: ["PT"] };
var people2 = { name: 'Andrew', age: '30', values: [{ pippo : 1}] };
const person2 = { age: '31', values: [{ pippo : 2}] };
// Now merge person back into people array
console.log(_.merge({}, people, person));
console.log(_.merge({}, people2, person2));
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.20/lodash.min.js"></script>
The result of first console.log is
{
age: "31",
name: "Andrew",
values: ["PT", "PORTA 31"]
}
And not as expected
{
age: "31",
name: "Andrew",
values: ["PT"]
}
Someone can explain me why and give me a solution to make sure that with a flat array it takes me the correct value
I think assign is better in this case than merge
This method is like _.assign except that it recursively merges own and inherited enumerable string keyed properties of source objects into the destination object. Source properties that resolve to undefined are skipped if a destination value exists. Array and plain object properties are merged recursively. Other objects and value types are overridden by assignment. Source objects are applied from left to right. Subsequent sources overwrite property assignments of previous sources.
var people = { name: 'Andrew', age: '30', values: ["PT", "PORTA 31"] };
const person = { age: '31', values: ["PT"] };
console.log(_.assign({}, people, person));
<script src="https://cdn.jsdelivr.net/npm/lodash#4.17.20/lodash.min.js"></script>
I believe _.assign(people, person) would produce the desired outcome in this case https://lodash.com/docs/4.17.15#assign
This functionality is also native and can be used like this Object.assign(target, source)

Clone a object only with few properties

Is there a way to clone an object with only few properties of the object in JS?
For example..
var Person = {
name: "Bob",
age: 32,
salary: 20000
};
I have to create another person object with just the name and age property so that it will look something like this :
var clonedPerson = {
name: "Bob",
age: 32
};
I could do a deep clone of the object and delete. But I wanted to know if there are better ways to do it.
Using the latest ES6, you can achieve this by the following code..
const Person = {
name: "Bob",
age: 32,
salary: 20000
};
const { salary , ...clonedPerson } = Person
console.log(clonedPerson)
More simple?
var Person = {
name: "Bob",
age: 32,
salary: 20000
};
var ClonedPerson = jQuery.extend({}, Person);
delete ClonedPerson.salary;
console.log(JSON.stringify(Person));
console.log(JSON.stringify(ClonedPerson));
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
an alternative approach using Array member methods:
var clone = Object.keys(Person) // convert to an Array of Person keys
.filter(function(key){return ["salary"].indexOf(key) == -1;}) // exclude key salary
.reduce(function(clone, current){clone[current] = Person[current]; return clone;}, {}); // convert back the array to a cloned literal object

Updating javascript object property?

I have a structure like the following:
skillet.person = {
name: {
first: '',
last: ''
},
age: {
current: ''
},
birthday: {
day: '',
month: '',
year: ''
}
}
I was wondering how I would update these values ? i.e. I though the following was correct
skillet.person.name.push({ first: 'blah', last: 'ha'});
but it's wrong ? How can I fix this ?
Using ES7+ syntax and a functional approach:
const new_obj = { ...obj, name: { first: 'blah', last: 'ha'} }
On recent browsers with ECMAScript 2015, you can do:
Object.assign(skillet.person.name, { first: 'blah', last: 'ha'});
which will preserve any existing attribute not listed in the right object.
Reference: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign
[EDIT] With ES7, you can do even shorter (but is it clearer?...):
{...skillet.person.name, ...{ first: 'blah', last: 'ha'}};
Reference: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax
As #ramon-diogo wrote with ES7+
I like to update nested values like:
let user = {
name: {
first: 'john',
last: 'smith'
},
age: 18,
city: 'new york'
}
const age = 20;
user = {...user, age}
console.log(user.age)
// output: 20
const newData ={
age: 22,
city: 'san francisco'
};
user = {...user,...newData}
console.log(user.name.first)
// output: john
console.log(user.age)
// output: 22
console.log(user.city)
// output: 'san francisco'
skillet.person.name.first = "blah"
skillet.person.name.last = "ha"
or
skillet.person.name = {first : "blah", last : "ha"}
If you want to mix an object into another one, you can use jQuery's deep extend function. "Deep" means that it does not overwrite name with the new object, but rather overwrites the properties inside such an object.
$.extend(true, skillet.person, {
name: {
first: 'updated'
},
birthday: {
day: 'updated',
year: 'updated'
}
});
Now, skillet.person has the appropriate properties updated, while the other properties are untouched.
push is a method of Arrays that adds a new item to an array.
If you want to replace the value then:
skillet.person.name = { … };
If you want to store multiple (full) names in the object, then you'll need the property to hold an array of objects instead of a single object.
I think that is simpler
let skillet = {
person: {
name : {
first: '',
last : ''
},
age : {
current: ''
},
birthday: {
day : '',
month: '',
year : ''
}
}
};
let update = {
person: {
name: {
first: 'blah',
last : 'ha'
}
}
};
let result = Object.assign(skillet.person, update.person);
console.log(result);
skillet.person.name.first = "blah"
skillet.person.name.last = "ha"
The easiest way.
skillset.person.name = {};
This is the easiest way to assign value to the property of an object.

Categories