if else statement javascript returns false statement - javascript

Could someone help me with this code, I'm trying to write a function that takes in a name from an object and returns a name tag :
"Hi! I'm [name], and I'm from [country]."
I've tried this code
const GUEST_LIST = {
Randy: "Germany",
Karla: "France",
Wendy: "Japan",
Norman: "England",
Sam: "Argentina"
}
function greeting(name) {
var x = Object.keys(GUEST_LIST);
const array = Object.keys(GUEST_LIST)
.map(function(key) {
return GUEST_LIST[key];
});
var txt ="";
for (let i in x)
{
if (name === x[i])
{
txt = "Hi I'm "+x[i] +", and I'm from " +array[i];
}
else
{
txt = "Hi! I'm a guest";
}
}
return txt;
}
console.log(greeting("Randy"))
but it always returns "Hi! I'm a guest" except when I type Sam,

Your issue is that your for loop will continue to loop over the other names in your x array even after you have found a name from your array that matches the name you passed into your function. That means on further iterations of your for loop, your else block of your code will run and overwrite the value of txt previously set. That's why "Sam" works, as that's the last name in your x array, and so txt doesn't get overwritten by further iterations of your for loop.
Another thing to note about your code, a for...in loop shouldn't be used to iterate over an array. It can lead to unwanted values being accessed, as it doesn't just loop over the indices of your array, but rather other properties.
With that being said, you're over-engineering your code. Currently, your object stores key-value pairs. The key is the name and the value is the country. For each key in your object, you can access it using bracket-notation:
console.log(GUEST_LIST["Randy"]); // Germany
With that idea in mind, your name variable can be used as the key for your object, which can then be used to obtain the country. If the GUEST_LIST object doesn't contain your key (ie: the value returned by trying to access the key from your object is falsy), then you can return your default "Hi! I'm a guest" text:
const GUEST_LIST = {
Randy: "Germany",
Karla: "France",
Wendy: "Japan",
Norman: "England",
Sam: "Argentina"
};
function greeting(name) {
const country = GUEST_LIST[name];
if(country)
return "Hi I'm "+name +", and I'm from " +country;
else
return "Hi! I'm a guest";
}
console.log(greeting("Randy"));

Since there are no specifications, why there should a for loop, why not make it a bit more simple?
const GUEST_LIST = {
Randy: 'Germany',
Karla: 'France',
Wendy: 'Japan',
Norman: 'England',
Sam: 'Argentina'
}
function greeting (name) {
if (GUEST_LIST[name]) {
return "Hi I'm " + name + ", and I'm from " + GUEST_LIST[name]
} else {
return "Hi! I'm a guest"
}
}
console.log(greeting('Randy'))
console.log(greeting('The guy from the bus stop'))

To appreciate what I mean here is the working version of your code.
for (let i in x)
{
if (name === x[i])
{
txt = "Hi I'm "+x[i] +", and I'm from " +array[i];
break; // <---- stop the loop here when you find a match
}
else
{
txt = "Hi! I'm a guest";
}
}
return txt;
}

Simple to read and short:
const GUEST_LIST = {
Randy: "Germany",
Karla: "France",
Wendy: "Japan",
Norman: "England",
Sam: "Argentina"
}
function greeting(name){
return (GUEST_LIST[name]) ?
`Hi, I'm ${name} and I'm from ${GUEST_LIST[name]}` :
`Hi! I'm a guest`
}
console.log(greeting("Randy"))

Related

Create One string from elements in an Array of Objects

I am trying to create ONE string from an array of objects family and have them separated by commas except for the last element Mary
const family = [
{Person: {
name: John
}}, {Person: {
name: Mike
}}, {Person: {
name: Link
}}
, {Person: {
name: Mary
}}];
I want the string to be like this
"John, Mike, Link or Mary"
I tried using family.toString() but that gives me "John, Mike, Link, Mary" and doesn't allow me to replace "," with an "OR"
Use pop() to get (and remove) the last name. Then use join() to add the rest.
Thx to #charlietfl for suggesting a check on the number of names to prevent something like: and John.
const family = [
{ Person: { name: "John" } },
{ Person: { name: "Mike" } },
{ Person: { name: "Link" } },
{ Person: { name: "Mary" } }
];
// Get all the names
const names = family.map((x) => x.Person.name);
// Get result based on number of names
let result = '';
if (names.length === 1) {
// Just show the single name
result = names[0];
} else {
// Get last name
const lastName = names.pop();
// Create result
result = names.join(', ') + ' and ' + lastName;
}
// Show output
console.log(result);
I don't think there's a super-elogant option. Best bet is something like:
function joinWord(arr, sep, finalsep) {
return arr.slice(0,-1).join(sep) + finalsep + arr[arr.length-1];
}
and then
joinWord(family.map(x=>x.person.name), ', ', ' or ');
You could make the invocation a little nicer at the cost of performance and modularity with:
Array.prototype.joinWord = function joinWord(sep, finalsep) {
return this.slice(0,-1).join(sep) + finalsep + this[this.length-1];
}
family.map(x=>x.person.name).joinWord(', ', ' or ')
But this is only a good idea if this is going to come up a lot within your program and your program is never going to be a part of something bigger. It effects every array.
How about
let sp = ' or ';
family.map(x => x.Person.name)
.reduceRight(
(x,y) => {
const r = sp + y + x;
sp = ', ';
return r;
}, '')
.replace(', ', '');
Hope, this question was for the school homework :)

Update 'nested' javascript object dynamically

I'm trying to create an object that is updated dynamically.
Here's the setup of the type of object I'd like to create (note: I may add other things, such as address, country, etc to the keys):
var contacts = {"Bruce Wayne":{"phone number":'123-456-7890', "email":"bwayne#night.com"}, "Alfred":{"phone number" :'987-654-3210', "email": "alfred#yourang.com"}, "Clark Kent":{"phone number":'951-753-8520', "email":"nothing#krypton.com"}}
So for each name (Bruce Wayne, Alfred, ...) I have some keys assigned to them.
I'm using npm faker to generate some fake data to try and populate an array like the above, with the outline
I'm able to get a loop going, but it always returns the last iteration's data. I understand it's because I'm doing contact = .... Since this is an object, I can't use push, AFAIK.
function getContact(numContacts){
contacts = {}
for (var i = 0; i < numContacts; i++){
console.log(i);
var name = faker.name.firstName() + " " + faker.name.lastName();
var phoneNum = faker.phone.phoneNumber();
var email = faker.internet.email();
contacts = {name :{ "phone number": phoneNum, "email": email}}
// contacts.name = {"phone number": phoneNum, "email":email}; // this also returns just the last instance.
};
return contacts;
};
var contacts = getContact(10); // This should create ten people, each with a phone number and email.
The loop almost successfully creates a single name. This returns:
name, 761.704.3328 x4287, Leopold81#hotmail.com
But in that iteration, name variable is actually Joe Schmoe, not literally name...
What am I overlooking to make sure that the contacts object gets populated with 10 people, with the resolved name, not just the last in the iteration?
Observations
You're trying to use name variable as key, however, what you're doing is adding a key literally called name.
What you have to do, is to create the key programmatically as follow: contacts[name] and assign the object with phoneNumber and Email.
This code is an example to simulate your scenario.
var faker = {
name: {
firstName: function() {
return "Clark";
},
lastName: function() {
return "Kent";
}
},
phone: {
phoneNumber: function() {
return '951-753-8520';
}
},
internet: {
"email": function() {
return "nothing#krypton.com";
}
}
};
function getContact(numContacts) {
var contacts = {}
for (var i = 0; i < numContacts; i++) {
var name = faker.name.firstName() + " " + faker.name.lastName();
var phoneNum = faker.phone.phoneNumber();
var email = faker.internet.email();
contacts[name + '_' + i] = {
"phone number": phoneNum,
"email": email
}
}
return contacts;
}
var contacts = getContact(10);
console.log(contacts);
The names are the keys in your object. You can use it like an array index to populate contacts. This should work:
contacts[name] = {"phone number": phoneNum, "email": email}

Filter JSON with unique key/values

I have a JSON object structured as such:
var theSchools = {
Bradley University: "bru",
Knox College: "knox",
Southern Illinois University Edwardsville: "siue",…
}
What I am trying to achieve is a way of retrieving the key, in this case the school name, by supplying the value, the schools 'code.'
It does not appear that I will be able to have this restructured correctly, i.e.
var theSchools = [
{
schoolName:"Bradley University",
schoolCode: "bru"
}
{
schoolName: "Knox College",
schoolCode: "knox"
}
]
so I'm kind of stuck with what I got.
I know the following code is incorrect, but it's essentially what I want to achieve:
if(getParameterByName("schoolId").length>0){
var schoolid = getParameterByName("schoolId");
var schoolName= theSchools.schoolid;
jQuery("h1").after("<h2>Welcome to <strong>"+schoolName+"</strong></h2>")
}
You can use a for...in loop to loop over each property in the object, and return the property name if the value matches:
var theSchools = {
"Bradley University": "bru",
"Knox College": "knox",
"Southern Illinois University Edwardsville": "siue"
};
function findSchool(code) {
for (var s in theSchools) {
if (theSchools[s] === code)
return s;
}
return null;
}
document.getElementById('school').innerText = findSchool('knox');
<div id="school"></div>
The question is if you really need it this way (see answer #James), here's what you requested:
var theSchools = {
"Bradley University": "bru",
"Knox College": "knox",
"Southern Illinois University Edwardsville": "siue"
}, schoolMap = {};
for (var schoolName in theSchools) {
var code = theSchools[ schoolName ];
schoolMap[ code ] = schoolName;
}
document.body.innerHTML = schoolMap["bru"]; // Bradley University
You don't have to use a for loop to check if property exists. Use hasOwnProperty method.
if (theSchools.hasOwnProperty("Knox College")) {
//do stuff
}
Working example: https://jsfiddle.net/7q9czdpc/

Accessing an Object literal key when its a string?

I want to make a comparison of an object literal which looks like so...
receipt.tab = {Cafe Latte: 4.75, Cappucino: 3.85}
The items are added when I call the method addItemAndPrice(item) as found bellow...
var Receipt = function(){
this.tab = {};
};
Receipt.prototype.addItemAndPrice = function(item){
if (comparisonHere???){
this.tab[item] = this.tab[item] + this.tab[item] = menu.prices[item];
} else {
this.tab[item] = menu.prices[item];
}
};
I want to call the method and if there is already a Cafe Latte found within the tab then I want to add the value of that item to the corresponding item value.
and create this...
receipt.tab = {Cafe Latte: 9.50, Cappucino: 3.85}
FYI menu looks like this...
var menu = {
"shopName": "The Coffee Connection",
"address": "123 Lakeside Way",
"phone": "16503600708",
"prices":
{
"Cafe Latte": 4.75,
"Flat White": 4.75,
"Cappucino": 3.85,
"Single Espresso": 2.05,
"Double Espresso": 3.75,
"Americano": 3.75,
"Cortado": 4.55,
"Tea": 3.65,
"Choc Mudcake": 6.40,
"Choc Mousse": 8.20,
"Affogato": 14.80,
"Tiramisu": 11.40,
"Blueberry Muffin": 4.05,
"Chocolate Chip Muffin": 4.05,
"Muffin Of The Day": 4.55
}
}
You can use the hasOwnProperty method to check if a property exists. If it does, you would just change the value:
Receipt.prototype.addItemAndPrice = function(item){
if (this.tab.hasOwnProperty(item)){
this.tab[item] += menu.prices[item];
} else {
this.tab[item] = menu.prices[item];
}
};
You can simplify this if you know that a valid value can never be false, or if that value can be considered zero. Then you can just replace any falsy value with zero and assign the sum:
Receipt.prototype.addItemAndPrice = function(item){
this.tab[item] = (this.tab[item] || 0) + menu.prices[item];
};
if (receipt.tab.hasOwnProperty(item)) {...} is best, because it catches cases where receipt.tab[item] is defined but falsy (like {'Caffe Latte': 0}), but in your case, if (receipt.tab[item]) {...} probably works because all falsy values should resolve to 0 anyway.

Find last JSON entry with value starting with

I need to find the key of last property starting with a string
JSON:
var data = {
"admin": "peterson",
"worker": "peter napier",
"housekeeper": "peterson",
"worker": "richard Ben",
"executive": "richard parker",
"executive": "peter alp",
"housekeeper": "richard johny",
"admin": "richardson"
};
I have to write an algorithm which will return the key corresponding to the last occurence of value starting with a string.
Ex: I need to get admin if I call findKey("richard")
I need to get executive if I call findKey("peter")
I have iterated the object using simple for loop as this
for (var key in yourobject) {
console.log(key, yourobject[key]);
}
But I like to know the fastest way of iterating this as my scenario has more than 100000 property.
Just iterate over your data and store each name beginning with your key :
function findkey(name) {
var lg = name.length,
found;
for(var line in data) {
if(data[line].length >= lg && data[line].substring(0,lg) === name) {
found = line;
}
}
return found;
}
Here you go
var findKey = function (string) {
var keyToReturn;
for(key in data){
if(data[key].indexOf(string) === 0)
keyToReturn = key;
}
return keyToReturn;
}

Categories