Iterate through an array of Objects - javascript

I need to loop through an array of objects, and prompt the user to enter a student's name. if the name exists I need to print the student's data to the screen or else keep on iterating until the user types quit.
The issue I have is, if I type the name of student of the last object, the student's records will not print until the loop completes.
Please see the code below:
var students = [{
name: 'hacene',
track: 'Full Stack JavaScript',
achievements: 12,
points: 1226
},
{
name: 'dave',
track: 'PHP Development',
achievements: 128,
points: 14868
},
{
name: 'layla',
track: 'iOS Development',
achievements: 8,
points: 901
},
{
name: 'mika',
track: 'Front-End Development',
achievements: 15,
points: 1666
},
{
name: 'heisenberg',
track: 'Blue Meth Manufacturing',
achievements: 99,
points: 9999
}
];
var student;
var records = '';
var search;
// Print function to print the content
function print(message) {
var outputDiv = document.getElementById('output');
outputDiv.innerHTML = message;
}
// Access each students records in the array / a loop is needed to achieve this
for (var i = 0; i < students.length; i++) {
student = students[i];
console.log(student);
search = prompt('Please enter a student\'s name to see his records: ');
search = search.toLocaleLowerCase();
console.log(search);
if (search === student.name) {
records += '<h2><strong>Student: ' + student.name + '</strong><h2>';
records += '<p>Track: ' + student.track + '</p>';
records += '<p>Points: ' + student.points + '</p>';
records += '<p>Achievements: ' + student.achievements + '</p>';
break;
} else if (search === 'quit') {
break;
}
}
// Print the students' name; track, achievments and points
print(records);
What I need is, to be able to print the records of a student, from the first prompt even if he's the last on the list.

What you have done it's more like a guessing game : "find the name of the current student in the for loop"
I don't know if you still need an answer but here you go :
You only have to put the prompt before the for loop.
After the prompt you do the loop and stop if you find a result.
var students = [{
name: 'hacene',
track: 'Full Stack JavaScript',
achievements: 12,
points: 1226
},
{
name: 'dave',
track: 'PHP Development',
achievements: 128,
points: 14868
},
{
name: 'layla',
track: 'iOS Development',
achievements: 8,
points: 901
},
{
name: 'mika',
track: 'Front-End Development',
achievements: 15,
points: 1666
},
{
name: 'heisenberg',
track: 'Blue Meth Manufacturing',
achievements: 99,
points: 9999
}
];
var student;
var records = '';
var search;
// Print function to print the content
function print(message) {
var outputDiv = document.getElementById('output');
outputDiv.innerHTML = message;
}
search = prompt('Please enter a student\'s name to see his records: ');
// Access each students records in the array / a loop is needed to achieve this
for (var i = 0; i < students.length; i++) {
student = students[i];
search = search.toLocaleLowerCase();
if (search === student.name) {
records += '<h2><strong>Student: ' + student.name + '</strong><h2>';
records += '<p>Track: ' + student.track + '</p>';
records += '<p>Points: ' + student.points + '</p>';
records += '<p>Achievements: ' + student.achievements + '</p>';
break;
}
}
// Print the students' name; track, achievments and points
print(records);
<div id="output"></div>
You can add a if statement on your loop.
if( search != "quit") {
for (var i = 0; i < students.length; i++) {
student = students[i];
search = search.toLocaleLowerCase();
if (search === student.name) {
records += '<h2><strong>Student: ' + student.name + '</strong><h2>';
records += '<p>Track: ' + student.track + '</p>';
records += '<p>Points: ' + student.points + '</p>';
records += '<p>Achievements: ' + student.achievements + '</p>';
break;
}
}
}
With it, if you type quit you will not enter in the loop.
Even if it not fill your requirement the better way of doing it is using find method.
var students = [{
name: 'hacene',
track: 'Full Stack JavaScript',
achievements: 12,
points: 1226
},
{
name: 'dave',
track: 'PHP Development',
achievements: 128,
points: 14868
},
{
name: 'layla',
track: 'iOS Development',
achievements: 8,
points: 901
},
{
name: 'mika',
track: 'Front-End Development',
achievements: 15,
points: 1666
},
{
name: 'heisenberg',
track: 'Blue Meth Manufacturing',
achievements: 99,
points: 9999
}
];
var student;
var records = '';
var search;
// Print function to print the content
function print(message) {
var outputDiv = document.getElementById('output');
outputDiv.innerHTML = message;
}
function write(student) {
records += '<h2><strong>Student: ' + student.name + '</strong><h2>';
records += '<p>Track: ' + student.track + '</p>';
records += '<p>Points: ' + student.points + '</p>';
records += '<p>Achievements: ' + student.achievements + '</p>';
print(records);
}
search = prompt('Please enter a student\'s name to see his records: ');
student = students.find((element) => {
if (element.name == search) {
return true;
}
})
if (student) {
write(student);
};
// Print the students' name; track, achievments and points
<div id="output"></div>

Instead of looping over students to prompt the user, you need to continue prompting the user until they enter quit or you have a match.
Something like this:
var quit = false
while(!quit) {
search = prompt('Please enter a student\'s name to see his records: ');
search = search.toLocaleLowerCase();
if (search === 'quit') {
quit = true;
continue;
}
// search for student here and if match is found then set quit to true
}

I need to loop through an array of objects, and prompt the user to enter a student's name. if the name exists I need to print the student's data to the screen or else keep on iterating until the user types quit.
You need to rethink your algorithm:
get input from user
while user does not enter "quit"
for each object in list
if name is the same as input
output the record
get input from user
Note that you need to get the input from the user then iterate over the list to search for the correct object.
Alternatively, you could use an object instead of a list. This outer object would have the student's name as a key and the object record as a value. Now you can index on the student's name that the user inputs to get the record directly rather than searching through a list.

Related

how can I display the child object values(children) with the main object?

let state=["Karnataka","Andharapradesh","Tamilnadu"];
console.log(state);
document.write("<br>"+state);
for (i=0;i<=state.length-1;i++){
document.write(state[i]);
}
// -- question part--
let person = {
name: prompt("Your name"),
age: prompt("age?"),
spouse:prompt("spouse name"),
address: prompt("enter your address"),
children :{
child1: "kamal",
child2: prompt("name of the child"),
}
}
console.log(person);
for(let values in person){
document.write( "<br>" + values + ":" + person[values]);
}
// output
Karnataka,Andharapradesh,Tamilnadu
name:jashdk
age:khsald
spouse:kashdl
address:lksadlka
children:[object Object]
// it will display only main object values and the child value as children:[object Object]
You could make a tree search like this:
const treeSearch = (obj) => {
for(let values in obj) {
document.write("<br>" + values + ":" + obj[values]);
}
}
Then you can implement that by checking if the person object contains a object as one of it's keys values.
// Full Code
let person = {
name: prompt("Your name"),
age: prompt("age?"),
spouse:prompt("spouse name"),
address: prompt("enter your address"),
children :{
child1: "kamal",
child2: prompt("name of the child"),
}
}
const treeSearch = (obj) => {
for(let values in obj) {
document.write("<br>" + values + ":" + obj[values]);
}
}
for(let values in person){
if(typeof person[values] == "object") {
treeSearch(person[values]);
} else {
document.write( "<br>" + values + ":" + person[values]);
}
}
That should work.

I get an "undefined" in my Javascript loop [duplicate]

This question already has answers here:
Why is there "undefined" text in the beginning of my string?
(3 answers)
Closed 4 years ago.
I have a code like this:
var students = [
{
name: 'Mustafa',
track: 'A',
achievements: 5,
points: 500
},
{
name: 'Ersin',
track: 'B',
achievements: 6,
points: 600
},
{
name: 'Ahmet',
track: 'C',
achievements: 7,
points: 700
},
{
name: 'Mehmet',
track: 'D',
achievements: 8,
points: 800
},
{
name: 'Cafer',
track: 'E',
achievements: 9,
points: 900
}
];
var HTML;
var s = 0;
function print(message) {
var outputDiv = document.getElementById('output');
outputDiv.innerHTML = message;
}
for (var s = 0; s < students.length; s += 1) {
HTML += '<h2>' + 'Student: ' + students[s].name + '</h2>' ;
HTML += '<p>' + 'Track: ' + students[s].track + '</p>';
HTML += '<p>' + 'Points: ' + students[s].points + '</p>';
HTML += '<p>' + 'Achievements: ' + students[s].achievements + '</p>';
};
print(HTML);
<div id="output"></div>
Unfortunately, only bad-outcome for this code is an "undefined" at the beginning. I would like to get rid of this.
Is it something about my loop or any other detail that i couldn't predict?
var HTML;
You don't explicitly give the variable a value when you initialise it, so it is undefined.
The first time you append to the variable with +=, that value gets implicitly converted to the string "undefined".
Use var HTML = ""; instead.
Initialize HTML to "", you are getting undefined since HTML (since it is not initialized) is undefined
var HTML = ""; //change this line
Demo
var students = [
{
name: 'Mustafa',
track: 'A',
achievements: 5,
points: 500
},
{
name: 'Ersin',
track: 'B',
achievements: 6,
points: 600
},
{
name: 'Ahmet',
track: 'C',
achievements: 7,
points: 700
},
{
name: 'Mehmet',
track: 'D',
achievements: 8,
points: 800
},
{
name: 'Cafer',
track: 'E',
achievements: 9,
points: 900
}
];
var HTML = ""; //change this line
var s = 0;
function print(message) {
var outputDiv = document.getElementById('output');
outputDiv.innerHTML = message;
}
for (var s = 0; s < students.length; s += 1) {
HTML += '<h2>' + 'Student: ' + students[s].name + '</h2>' ;
HTML += '<p>' + 'Track: ' + students[s].track + '</p>';
HTML += '<p>' + 'Points: ' + students[s].points + '</p>';
HTML += '<p>' + 'Achievements: ' + students[s].achievements + '</p>';
};
print(HTML);
<div id="output"></div>
Initialize HTML variable with an empty string like this:
var HTML="";

Looping through 'layered' javascript dictionary

I'm trying to create a dictionary (I think that's the best option...) for setting up a type of address book. The idea is to return something like
contacts = {"Bruce Wayne":{"phone number":'123-456-7890', "car":"All of them"}, "Alfred":{"phone number" :'987-654-3210', "car": "limo"}, "Clark Kent":{"phone number":'951-753-8520', "car":"None, flying works."}}
This works. I can do say console.log(contacts["Bruce Wayne"]) and it returns:
{ 'phone number': '123-456-7890', car: 'All of them' }
Doing console.log(contacts["Bruce Wayne"]["phone number"]) correctly returns
123-456-7890
However, I can't figure out how to loop through each person, and then each person's phone number and car.
Using this:
for (const[key, value] of Object.entries(contacts)){
console.log(contacts[key]);
}
just returns
[object Object]
[object Object]
[object Object]
I'm trying to get (psuedo code)
[First key], [key] is [value], [key] is [value]
Bruce Wayne, phone number is 123-456-7890, car is All of them
Alfred, phone number is 987-654-3210, car is limo
Edit: I also tried
for (var person in contacts){
console.log(contacts[person])
}
which also returns [object Object]...
try this:
for (let i in contacts) {
console.log(i + ',' + JSON.stringify(contacts[i]).replace(/\":\"/g, ' is ').replace(/["{}]/g, ''));
}
or
let contacts = { "Bruce Wayne": { "phone number": '123-456-7890', "car": "All of them" }, "Alfred": { "phone number": '987-654-3210', "car": "limo" }, "Clark Kent": { "phone number": '951-753-8520', "car": "None, flying works." } }
function consoleObj(obj, separator, attrIntro) {
let result = '';
for (let name in obj) {
result += name + separator;
for (let attr in obj[name]) {
result += attr + attrIntro + obj[name][attr] + separator;
}
result += '\n';
}
return result;
}
console.log(consoleObj(contacts, ',', ' is '));
or this
function consoleObj(obj, separator, attrIntro) {
return Object.keys(obj).reduce(function(result, name) {
result += name + separator;
Object.keys(obj[name]).forEach(function(attr) {
result += attr + attrIntro + obj[name][attr] + separator;
});
result += '\n';
return result;
}, '');
}
console.log(consoleObj(contacts,',',' is '));
Your for..of loop is giving you the name and the object with the properties, so you need to change how you access the "phone number" and "car" to details['phone number'] etc...
const contacts = {"Bruce Wayne":{"phone number":'123-456-7890', "car":"All of them"}, "Alfred":{"phone number" :'987-654-3210', "car": "limo"}, "Clark Kent":{"phone number":'951-753-8520', "car":"None, flying works."}}
// join an object
const joinObject = (obj, glue = 'is', joiner = ', ') =>
Object.keys(obj)
.map(k => `${k} ${glue} ${obj[k]}`)
.join(joiner)
// fixed string
for (const [name, details] of Object.entries(contacts)) {
console.log(`${name}, phone number is ${details['phone number']}, car is ${details['car']}`);
}
// dynamic property description
for (const [name, details] of Object.entries(contacts)) {
console.log(name + ' ' + joinObject(details))
}

Javascript object returns undefined

var movies =
[
{name: "In Bruges", rating:"4.7", seen:false},
{name: "Frozen", rating: "4.5", seen:true},
{name: "Lion King", rating:"5", seen:true},
]
for (var i = 0; i < movies.length; i++) {
var result = "You have ";
if(movies.seen === true){
result += "watched ";
}
else{
result += "not seen ";
}
result += "\"" + movies.name + "\" - ";
result += movies.rating + " stars"
console.log(result)
};
You have not seen "undefined" - undefined stars is the result in chrome however you should see You have seen/not seen "movie name" - "rating" stars.
I need to use for loop to print out what each movie I have watched and rating and if I have seen it or not. Question is why is it undefined? Should the code see movies.rating and just substitute the value there? Can some one check my code and help me with my for loop?
movies is an array movies.seen won't work use movies[i].seen and like wise for other properties
Change movies.seen, movies.rating and movies.name to movies[i].seen, movies[i].rating, and movies[i].name.
Use index to access item of array; e.g. movies[i]:
for (var i = 0; i < movies.length; i++) {
var result = "You have ";
if(movies[i].seen === true){
result += "watched ";
}
else{
result += "not seen ";
}
result += "\"" + movies[i].name + "\" - ";
result += movies[i].rating + " stars"
console.log(result)
}
Or you could store the array item in a variable and use it like this:
for (var i = 0; i < movies.length; i++) {
var movie = movies[i];
var result = "You have ";
if (movie.seen) {
result += "watched ";
}
else {
result += "not seen ";
}
result += '"' + movie.name + '" - ';
result += movie.rating + " stars";
console.log(result);
}
Here is a working Plunker for you to see it working. :)
var movies =
[
{name: "In Bruges", rating:"4.7", seen:false},
{name: "Frozen", rating: "4.5", seen:true},
{name: "Lion King", rating:"5", seen:true},
]
for (var i = 0; i < movies.length; i++) {
var result = "You have ";
if(movies[i].seen === true){
result += "watched ";
}
else{
result += "not seen ";
}
result += "\"" + movies[i].name + "\" - ";
result += movies[i].rating + " stars"
alert(result)
}
You were trying to access properties of movies called seem, name and rating, but movies has 3 objects indexed from 0 to 2.
You are using movies inside loop and movies do not contain those properties.
And it is allways safe to use forEach loop while iterating arrays
Do something like
movies.forEach(function(movie){
var result = "You have ";
if(movie.seen === true){
result += "watched ";
}
else{
result += "not seen ";
}
result += movie.name + " - ";
result += movie.rating + " stars";
console.log(result);
});
I suggest to use a little other approach to iterate over the array and for the check if a movie has been seen.
var movies = [
{ name: "In Bruges", rating: "4.7", seen: false },
{ name: "Frozen", rating: "4.5", seen: true },
{ name: "Lion King", rating: "5", seen: true },
];
movies.forEach(function (movie) {
var result = "You have ";
result += movie.seen ? "watched " : "not seen ";
result += "\"" + movie.name + "\" - ";
result += movie.rating + " stars"
document.write(result + '<br>');
});

How to format a text in a mailto function

I have two arrays and an object. One array conatins product codes, and another contains the quantities thereof. For example, the first quantity in the quantities array is the quantity of the product code that is the first one in the product code array. I also have an object that contains customer data. It would look something like this:
customer={
name:' firstname lastname',
email: 'example#domain.com',
company: "company name",
phone_number: 'phone number',
}
the arrays would look like this:
product_codes=[code_1; code_2; code_3];
quantities=[23, 56, 45];
Say that all of this is being mailed to customersupport#example.com.
I am familiar with the basics of the mailto function, but I would like to know if there is a way to format the body of the email so that it looks something like this:
...................................
Name: customer.name
email: customer.email
company name: customer.company
phone number: customer.phone_number
product code 1: corresponding quantity
product code 2: corresponding quantity
product code 3: corresponding quantity
...............................................
I would also like to be able to add any other given codes and quantities, as I am not sure of how many there will be. Is this even possible? If so, how? Please explain so that I can not only use it, but also understand how it works. Thanks!
If I'm not being clear enough, please let me know so I can edit it for greater clarity.
var sendEmail = function() {
var customer, body, quantities, product_codes;
customer = {
name: 'First Last',
email: 'example#example.com',
company: 'Company',
phone_number: 'phone number',
}
body = 'Name: '+ customer.name;
body += '\nEmail: '+ customer.email;
body += '\nCompany: '+ customer.company;
body += '\nPhone Number: '+ customer.phone_number;
product_codes = ['code_1', 'code_2', 'code_3'];
quantities = [23, 56, 45];
for(var i = 0; i < product_codes.length; i += 1) {
body += '\nProduct Code '+ product_codes[i] +': '+ quantities[i];
}
subject = 'Your Subject';
window.location = 'mailto:customersupport#example.com?body='+ encodeURIComponent(body) +'&subject='+ encodeURIComponent(subject);
};
// execute this function when the user clicks the #send-email button
var button = document.getElementById('send-email');
button.addEventListener('click', sendEmail);
I would build the string in a function:
HTML:
Click to Email
JAVASCRIPT:
//stuff you specified...
var customer={
name:' firstname lastname',
email: 'example#domain.com',
company: "company name",
phone_number: 'phone number',
}
var product_codes=['alpha', 'beta', 'gamma'];
var quantities=[23, 56, 45];
/* Assign a click action onto the link */
var yourLink = document.getElementById("thelink");
yourLink.onclick = function() {
var elf = "%0A"; //Encoded Line Feed
mailtoBody = "Name: " + customer.name + elf
+ "Email: " + customer.email + elf
+ "Company Name: " + customer.company + elf
+ "Phone Number: " + customer.phone_number + elf;
for (var i=0; i < product_codes.length; i++) {
mailtoBody += product_codes[i] + ": " + quantities[i] + elf;
}
location.href = "mailto:you#example.com?body=" + mailtoBody;
}
Here's a working example:
http://jsbin.com/kigutuhiqa/edit?html,js,output
It sounds to me like you want to construct the body of a message. If this is the case, you can create a function that builds the body of your message by taking in the 3 objects you mentioned: customer, codes, and quantity.
For example, you can do something like
function buildBody(cust, codes, quant){
var body = "";
body += "Name: " + cust.name + "\n";
body += "Email: " + cust.email + "\n";
body += "Company Name: " + cust.companyname + "\n";
for(var i=0; i<codes.length; ++i)
body += "Product Code " + codes[i] + ": " quant[i] + "\n";
return body;
}
I have not tested this code, but hopefully you get the idea.

Categories

Resources