I'm a bit confused with objects in JavaScript...
I wrote an object:
const gix = {
firstName: "John",
lastName: "Johnson",
yearOfBirth: 2000,
profession: "IT",
friends: ["Mark", "Luke", "John"],
driversLicence: true,
age: function () {
this.calcAge = 2022 - this.yearOfBirth;
return this.calcAge;
},
};
gix.age();
console.log(gix);
Why is the console log of the whole object not showing the calculated value but is showing age: f()
Considering your use-case, you could replace the method with a getter, which gets evaluted each time the object is referenced:
const gix = {
firstName: "John",
lastName: "Johnson",
yearOfBirth: 2000,
profession: "IT",
friends: ["Mark", "Luke", "John"],
driversLicence: true,
get age() {
return 2022 - this.yearOfBirth;
},
};
You would either want to capture the return value of the function or call it so:
console.log(gix.age());
Think of age as a pointer to the function...
When you're console logging a function it wont execute it, It will just show the contents of the function, IF you need to see the value then you need to call the function and log the output
console.log(gix.age());
If you check the log, it actually added calcAge as you already called age before. If you want to use a computed property calcAge from yearOfBirth, you can use Object getters
const gix = {
firstName: "John",
lastName: "Johnson",
yearOfBirth: 2000,
profession: "IT",
friends: ["Mark", "Luke", "John"],
driversLicence: true,
get calcAge () { return 2022 - this.yearOfBirth; },
};
console.log(gix.calcAge);
Related
Working on an assignment. I am using .filter() to find a list of active members. Following the instructions of the assignment the output is very messy. I would like to only display the member names or the member _ids.
This is the helper function and I cannot modify this function. As a rule of the assignment.
const printKata = function (kataNumber, object) {
const detailsElement = document.createElement("details");
main.append(detailsElement);
const summaryElement = document.createElement("summary");
summaryElement.append("KATA " + kataNumber);
detailsElement.append(summaryElement);
const stringifiedObject = JSON.stringify(object);
detailsElement.append(stringifiedObject);
...
Here is an example of the user object
const users = [
{
_id: "5efb83d333dadb00fc5f68e4",
isActive: true,
balance: "$2,967.17",
picture: "http://placehold.it/32x32",
age: 21,
eyeColor: "green",
name: "Gregory Villarreal",
company: "BLUPLANET",
email: "undefined.undefined#bluplanet.name",
phone: "+1 (866) 544-2326",
registered: "Friday, May 24, 2019 3:08 PM",
tags: ["quis", "irure", "consequat", "ut", "occaecat"],
}
...
And here is the simple function to filter the data.
let userActive = users.filter(function (user) {
return user.isActive === true;
});
...
Currently it is displaying all the data from the entire object. I think it would look a lot nicer to only display the name and or id ..
I am very new to all of this. Please be patient with me.
Currently it is displaying all the data from the entire object. I
think it would look a lot nicer to only display the name and or id ..
To do that, Use map just after your filter method, to specify only fields you want from objects and not all of them.
const users = [{
_id: "5efb83d333dadb00fc5f68e4",
isActive: true,
balance: "$2,967.17",
picture: "http://placehold.it/32x32",
age: 21,
eyeColor: "green",
name: "Gregory Villarreal",
company: "BLUPLANET",
email: "undefined.undefined#bluplanet.name",
phone: "+1 (866) 544-2326",
registered: "Friday, May 24, 2019 3:08 PM",
tags: ["quis", "irure", "consequat", "ut", "occaecat"],
}]
let userActive = users.filter(function(user) {
return user.isActive === true;
}).map(({id,name})=>({id,name}));
console.log(userActive)
This function is returning what you are asking from it:
let userActive = users.filter(function (user) {
return user.isActive === true;
});
"Filter the users array and return the user where isActive is true."
The return is the user object (or users if there is more than one) with all the key/value pairs.
As suggested in the previous answer, you can chain the map method at the end and return the values you want.
I have a var named onversation that contains this:
{
"conversationId": "adbabc54-3308-436d-a48b-932f4010d3c6",
"participantId": "415651e6-f0a5-4203-8019-4f88c3ed9cd5"
}
I also have an object named person that contains this:
{
firstname: "fred",
surname: "smith",
age: "21",
gender: "male"
}
What I'd like is to have a combined object called result that looks like this
result {
conversation {
conversationId : adbabc54-3308-436d-a48b-932f4010d3c6,
participantId : 415651e6-f0a5-4203-8019-4f88c3ed9cd5
},
person {
firstname: "fred",
surname: "smith",
age: "21",
gender: "male"
}
}
How would I do this dynamically whereby the result object is built using the name of the var 'conversation' and name of the object 'person' ?
Also, the length of either conversation or person can be any length.
Pure JavaScript if possible , but could use underscore etc.
Try it
var result = {
'conversation': conversation,
'person': person
}
Dynamic
var result = {}
result['person'] = person
or
resilt.person = person
If I understand your question correctly, you can use object shorthand notation which is supported in most browsers (Probably all of them, except IE11) for simplifying your solution even more:
var conversation =
{
conversationId : 'adbabc54-3308-436d-a48b-932f4010d3c6',
participantId : '415651e6-f0a5-4203-8019-4f88c3ed9cd5'
};
var person =
{
firstname: "fred",
surname: "smith",
age: "21",
gender: "male"
};
var result = { conversation, person }
console.log(result)
EDIT:
If only the variable name changes, and it's properties names stay the same or have some sort of unique key, you can use a for loop on the object's keys.
For example:
var someConversationVariableName =
{
conversationId : 'adbabc54-3308-436d-a48b-932f4010d3c6',
participantId : '415651e6-f0a5-4203-8019-4f88c3ed9cd5'
};
var somePersonVariableName =
{
firstname: "fred",
surname: "smith",
age: "21",
gender: "male"
};
var result = { someConversationVariableName, somePersonVariableName }
for (key in result) {
if(result[key]['conversationId']) {
console.log(`Found conversation object. It's name is: ${key}`);
}
else if(result[key]['firstname']) {
console.log(`Found person object. It's name is: ${key}`);
}
}
If you need to defer adding objects, you can also take this approach:
var conversation =
{
conversationId : 'adbabc54-3308-436d-a48b-932f4010d3c6',
participantId : '415651e6-f0a5-4203-8019-4f88c3ed9cd5'
};
var person =
{
firstname: "fred",
surname: "smith",
age: "21",
gender: "male"
};
var result = {};
result['conversation'] = conversation;
result['person'] = person;
console.log(result);
This Must work :-
var conversation =
{
"conversationId": "adbabc54-3308-436d-a48b-932f4010d3c6",
"participantId": "415651e6-f0a5-4203-8019-4f88c3ed9cd5"
}
var person=
{
firstname: "fred",
surname: "smith",
age: "21",
gender: "male"
}
var result = {
'conversation': conversation,
'person': person
}
<script>
<!-- A program to search for a friend from an object -->
var friends = {
bill: {
firstName: "Bill",
lastName: "Gates",
number: "205-555-1111",
address:["One Microsoft Day","Redmond","WA","90852"]
},
steve: {
firstName: "Steve",
lastName: "Jobs",
number: "408-555-2222",
address: ["One Infinite Loop", "Cupertino", "CA", "95014"]
},
wendy: {
firstName: "Wendy",
lastName: "Johnson",
number: "510-555-3333",
address: ["3555 Anyplace drive","New York", "NY","11001"]
}
}
alert(friends["steve"].lastName);
alert(friends.length);
var search = function(name)
{
document.write(name);
for (var nameSearch in friends)
{
alert(nameSearch.firstName);
if(friends[nameSearch].firstName===name)
{
return friends[nameSearch];
}
}
}
search("Wendy");
</script>
Theres a couple things wrong with your code:
Objects do not have a length property so the second alert for friends.length will not work
When you're using for in you are referencing the key of the object, so in this case it will be bill, steve, or wendy so when you do nameSearch.firstName it will be undefined since nameSearch is a string
Finally, the reason that your example is failing is because you're searching against case-sensitive text. wendy != Wendy. Also please keep in mind that triple equals checks the constructor.
To fix your code, you can try just lower-casing all of your search text:
var friends = {
bill: {
firstName: "Bill",
lastName: "Gates",
number: "205-555-1111",
address:["One Microsoft Day","Redmond","WA","90852"]
},
steve: {
firstName: "Steve",
lastName: "Jobs",
number: "408-555-2222",
address: ["One Infinite Loop", "Cupertino", "CA", "95014"]
},
wendy: {
firstName: "Wendy",
lastName: "Johnson",
number: "510-555-3333",
address: ["3555 Anyplace drive","New York", "NY","11001"]
}
};
var search = function(name) {
for (var nameSearch in friends) {
if(friends[nameSearch].firstName.toLowerCase()===name.toLowerCase()) {
return friends[nameSearch];
}
}
}
console.log(search("wendy"));
Given the following data:
const my_data = [
{
name: "John",
age: 22
},
{
name: "Johnny",
age: 15
},
{
name: "Dave",
age: 27
}
]
I want to transform the data such that the substring "John" is replaced with "Ben" in each of the name properties so it looks like this:
[
{
name: "Ben",
age: 22
},
{
name: "Benny",
age: 15
},
{
name: "Dave",
age: 27
}
]
I want to do so in the proper functional way (I think is points-free but I am still learning), so I can reuse this in a pipeline, say first reducing by age and then doing the replace, or doing the replace first then doing a sort. How would I do this using the Ramda functions?
var fix_names = ???
var fixed_data = R.map( fix_names, my_data );
R.map(R.over(R.lensProp('name'), R.replace('John', 'Ben')))(my_data)
See R.over and R.lensProp.
There's no reason to prefer point-free functions. Readability is what really matters:
var myData = [ new Person("John", 22)
, new Person("Johnny", 15)
, new Person("Dave", 27)
];
var fixedData = myData.map(fixName);
alert(JSON.stringify(fixedData, null, 4));
function fixName(person) {
return Object.assign(new Person, person, {
name: person.name.replace(/John/g, "Ben")
});
}
function Person(name, age) {
this.name = name;
this.age = age;
}
Point-free functions are useful in very limited cases like eta conversion and function composition. Point-free functions should not be treated as the cornerstone of functional programming.
var obj = {
customerInfo: {
fname: "Tom",
lname: "Smith",
age: 23,
height: 160
},
car: {
color: "red",
numWheels: 4
}
};
I would like to modify this object into:
var obj = {
customerInfo: {
fname: "Sally",
lname: "Adams",
mname: "Tully",
age: 23,
height: 160
},
car: {
color: "red",
numWheels: 4
}
};
However, if I do
_.extend(obj, {
customerInfo: {
fname: "Sally",
lname: "Adams",
mname: "Tully"
}
});
the object becomes
{
customerInfo: {
fname: "Sally",
lname: "Adams",
mname: "Tully"
},
car: {
color: "red",
numWheels: 4
}
};
and the age and height have been wiped out.
What do I need to do to preserve data that's nested?
And what about updating more complex objects?
http://jsfiddle.net/j4L18p7k/2/#share
There are better ways of achieving this deep merge behavior you're actually looking for...
You could use Jquery's $.extend API as documented here: http://api.jquery.com/jquery.extend/
I've put together this little example to match your code sample since I believe you that this kind of generic approach to merging is what you're actually looking for, right?
var o = {
customerInfo: {
fname: "Tom",
lname: "Smith",
age: 23,
height: 160,
paymentMethods: {
paypal: {
username: "sally"
}
}
},
car: {
color: "red",
numWheels: 4
}
};
// this wipes out more deeply nested things (paypal disappears)
var merge = $.extend(true, {} , o.customerInfo, {
"fname": "Sally",
lname: "Adams",
mname: "Tully",
paymentMethods: {
visa: {
lastFour: "5555"
}
}
});
console.dir(merge);
http://jsfiddle.net/hrqbyd5c/9/
However pay attention to the JQuery docs
On a deep extend, Object and Array are extended, but object wrappers on primitive types such as String, Boolean, and Number are not. Deep-extending a cyclical data structure will result in an error.
For needs that fall outside of this behavior, write a custom extend method instead, or use a library like lodash.
Check out lodash's merge API documentation https://lodash.com/docs#merge
Hope this helped some more...
Extend customerInfo directly. Underscore .extend() replaces any key you mention, in this case removing any previous nested keys that aren't in your new object.
_.extend(obj.customerInfo, {
fname: "Sally",
lname: "Adams",
mname: "Tully"
});