I was just wondering is it possible to remove extra unknown properties from object.
The exact problem which I am facing is that I know what fields I need in object, but I don't know what extra is coming and I need to remove those extras.
One option which comes in my mind is using hasOwnProperty function since we know what all properties we need.
Ex : Suppose we are getting below object :
{
name: "Harry",
age: 16,
gender: "Male",
Address: {
prop1: "Hello",
City: "LA"
}
}
Now, we know that we need name, age, address and city in address beforehand but we are getting prop1 also as extra here and we don't know that it is exactly. It could be anything. We need to remove this prop1 from this object. This is just an example.
I think we need to use some recursive approach because the extra property could be at any place in the object.
Note: We have a list of properties which we need in advance.
I defined a schema form of json (modify it as you want) and then I made a function that receives the json required to delete unwanted elements from it.
const needAttribute = {
name: "Harry",
age: 16,
gender: "Male",
Address: {
City: "LA"
}
}
var json =
{
name: "Harry",
age: 16,
gender: "Male",
Address: {
prop1: "Hello",
City: "LA"
}
}
function getNeedAttributeFromJson(Myjson){
for(var element in Myjson){
if(needAttribute.hasOwnProperty(element)){
if (typeof Myjson[element] === "object") {
for(var subElement in Myjson[element]){
if(!needAttribute[element].hasOwnProperty(subElement)){
delete Myjson[element][subElement];
}
}
}else{
continue;
}
}else{
delete Myjson[element];
}
}
return Myjson;
}
console.log(getNeedAttributeFromJson(json));
You can use lodash library.
REFERENCE URL - https://lodash.com/docs/4.17.15#omit
const object = {
name: "Harry",
age: 16,
gender: "Male",
Address: {
prop1: "Hello",
City: "LA"
}
object = _.omit(object.Address, 'prop1');
console.log(object);
Related
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);
let Name = {
get fullname() {
return this.fname + this.last
}
}
function pension() {
return this.age > 60
}
let firstclass_employee = [{
fname: "sangeth",
last: "AV",
age: 21,
address: {
housename: "good house",
place: "goodplace",
city: "goodtwon",
postcode: 121212
},
hobbies: ["driving", "travelling", "sports"]
}, {
fname: "ramu",
last: "kv",
age: 29,
address: {
housename: "etho veedu",
place: "vayadi",
city: "kalur",
postcode: 11111
},
hobbies: ["travelling", "sports"]
}]
console.log(" objects::\t", Name, "\n", firstclass_employee)
//calling a out side function for an object(out side function may be inside an object oe not)
console.log("Fullname of first employee::", Name.fullname.call(firstclass_employee[0]))
console.log("Pension status of of first emlpoyee::", pension.call(firstclass_employee[0]))
console.log("Fullname of 2nd employee::", Name.fullname.call(firstclass_employee[1]))
console.log("Pension status of of 2nd emlpoyee::", pension.call(firstclass_employee[1]))
AND getting error--->
console.log("Fullname of first employee::", Name.fullname.call(firstclass_employee[0]))
^
TypeError: Name.fullname.call is not a function
remove get - which is not a valid here
let Name = {
fullname() {
return this.fname + this.last
}
}
If you want regular function remove the get and it will work fine. Sorry, I was mistakenly said you have errors in the console.log() part.
let Name = {
fullname() {
return this.fname + this.last
}
}
function pension() {
return this.age > 60
}
let firstclass_employee = [{
fname: "sangeth",
last: "AV",
age: 21,
address: {
housename: "good house",
place: "goodplace",
city: "goodtwon",
postcode: 121212
},
hobbies: ["driving", "travelling", "sports"]
}, {
fname: "ramu",
last: "kv",
age: 29,
address: {
housename: "etho veedu",
place: "vayadi",
city: "kalur",
postcode: 11111
},
hobbies: ["travelling", "sports"]
}]
console.log(" objects::\t", Name, "\n", firstclass_employee)
//calling a out side function for an object(out side function may be inside an object oe not)
console.log("Fullname of first employee::", Name.fullname.call(firstclass_employee[0]))
console.log("Pension status of of first emlpoyee::", pension.call(firstclass_employee[0]))
console.log("Fullname of 2nd employee::", Name.fullname.call(firstclass_employee[1]))
console.log("Pension status of of 2nd emlpoyee::", pension.call(firstclass_employee[1]))
As far as why the call() is invalid is that Name.fullname is not exposed as a function. It is exposed the same way as a field would be, e.g.
const Name = {
fullname: 'Bob'
};
With that structure, you wouldn't expect to be able to call Name.fullname.call, right? But for the purposes of getting the value, that's what the prior code exposed to the outside world (the difference with the field being that you can set the value, whereas with a getter and no setter, the property is read only).
The get essentially tells the JavaScript engine that, whenever someone asks for the value of fullname, give them the value of the fname and last properties concatenated together.
Thus, when you ask for Name.fullname.call(firstclass_employee[0]) it first finds Name. Then it asks for the value of fullname. It gets back NaN, because this is the Name object and it doesn't have fname or last properties, and it tries to coerce the first undefined (from this.fname) to a Number for the addition operator, and gets NaN. Then it tries to get the call function on NaN, and there is no such thing, so it throws an error.
It appears as though you want to be able to get a full name from any object that has fname and last properties. I would suggest using static method for that rather than an instance property getter.
Similarly, a static method would work for determining employees who get a pension.
Personally, I would just create a class or series of classes that I could compose together to bring this functionality together, rather than trying to use call, but that's me.
const Name = {
fullName(obj) {
return `${obj.fname} ${obj.last}`;
}
};
const Pay = {
getsPension(obj) {
return obj.age > 60;
}
}
let firstclass_employee = [{
fname: "sangeth",
last: "AV",
age: 21,
address: {
housename: "good house",
place: "goodplace",
city: "goodtwon",
postcode: 121212
},
hobbies: ["driving", "travelling", "sports"]
}, {
fname: "ramu",
last: "kv",
age: 29,
address: {
housename: "etho veedu",
place: "vayadi",
city: "kalur",
postcode: 11111
},
hobbies: ["travelling", "sports"]
}]
console.log('should be sangeth AV: ', Name.fullName(firstclass_employee[0]));
console.log('should be false: ', Pay.getsPension(firstclass_employee[0]));
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.
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
I've this json return
data = [
{ firstName: "Christophe",
lastName: "Coenraets"},
{ firstName: "John",
lastName: "Smith"}
];
I want to display each object in a li list and want to use Enumerable condition. I understand if it'd been like
data = { elem :[
{ firstName: "Christophe",
lastName: "Coenraets"},
{ firstName: "John",
lastName: "Smith"}
]};
I can use something like
{{#elem}}
<li>{{firstName}} {{lastName}}</li>
{{/elem}}
But in the first case, how do I check the condition?
I don't work with icanhaz, it very well may have a method to parse the data that you get, but you could always modify the JSON object and wrap it into a parent element like in your second case:
myData = { elem : data};