-
Notifications
You must be signed in to change notification settings - Fork 0
/
app.js
459 lines (404 loc) · 15.3 KB
/
app.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
"use strict"
/*
Build all of your functions for displaying and gathering information below (GUI).
*/
// app is the function called to start the entire application
function app(people){
let searchType = promptFor("Do you know the name of the person you are looking for? Enter 'yes' or 'no'", yesNo).toLowerCase();
let searchResults;
switch(searchType){
case 'yes':
searchResults = searchByName(people);
break;
case 'no':
searchByTraits(people);
break;
default:
app(people); // restart app
break;
}
// Call the mainMenu function ONLY after you find the SINGLE person you are looking for
mainMenu(searchResults, people);
}
// Menu function to call once you find who you are looking for
function mainMenu(person, people){
/* Here we pass in the entire person object that we found in our search, as well as the entire original dataset of people. We need people in order to find descendants and other information that the user may want. */
if(person.length < 1) {
alert("Could not find that individual.");
return app(people); // restart
}
let displayOption = prompt("Found " + person[0].firstName + " " + person[0].lastName + " . Do you want to know their 'info', 'family', or 'descendants'? Type the option you want or 'restart' or 'quit'");
switch(displayOption){
case "info":
displayPerson(person);
break;
case "family":
immediateFamily(person, people,);
break;
case "descendants":
displayDescendants(person, people, 0);
break;
case "restart":
app(people); // restart
break;
case "quit":
return; // stop execution
default:
return mainMenu(person, people); // ask again
}
}
/*======================================================================*/
//function to search traits
function searchByTraits(people){
let chosenTraits = promptTraits("Please choose the traits for which you would like to search, leaving one space between each trait. For example: gender height weight eyecolor occupation");//Prompt to choose which traits to search for
let chosenTraitsArr = chosenTraits.split(" ");//Turn resulting string to array
let traitValuesArr = [];
for (let i = 0; i < chosenTraitsArr.length; i++) { //Iterate though the array to determine which traits were chosen
if (chosenTraitsArr[i].toLowerCase() === "gender") {
traitValuesArr.push(promptGender("Gender Search:" + "\n" + "Please enter either male or female.").toLowerCase());
// genderValue = prompt("Gender Search:" + "\n" + "Please enter either male or female.").toLowerCase();
}
else if (chosenTraitsArr[i] === "height") {
traitValuesArr.push(parseInt(promptHeightWeight("Height Search:" + "\n" + "Please enter an integer for height in inches without any punctuation.")));
// heightValue = prompt("Height Search:" + "\n" + "Please enter an integer for height in inches without any punctuation.");
}
else if (chosenTraitsArr[i] === "weight") {
traitValuesArr.push(parseInt(promptHeightWeight("Weight Search:" + "\n" + "Please enter an integer for weight in pounds without any punctuation.")));
// weightValue = prompt("Weight Search:" + "\n" + "Please enter an integer for weight in pounds without any punctuation.");
}
else if (chosenTraitsArr[i].toLowerCase() === "eyecolor") {
traitValuesArr.push(promptFor("Eye Color Search:" + "\n" + "Please enter a color.").toLowerCase());
// eyeColorValue = prompt("Eye Color Search:" + "\n" + "Please enter a color.").toLowerCase();
}
else if (chosenTraitsArr[i].toLowerCase() === "occupation") {
traitValuesArr.push(promptFor("Occupation Search:" + "\n" + "Please enter an occupation.").toLowerCase());
// occupationValue = prompt("Occupation Search:" + "\n" + "Please enter an occupation.").toLowerCase();
}
}
let searchResults = [];
let gender = [];
for (let i = 0; i < chosenTraitsArr.length; i++){
if (chosenTraitsArr[i] === "gender") {
gender = people.filter(function(list) {
if (list.gender === traitValuesArr[i]) {
return true;
}
else {
return false;
}
})
}
}
let height = [];
for (let i = 0; i < chosenTraitsArr.length; i++){
if (chosenTraitsArr[i] === "height") {
height = people.filter(function(list) {
if (list.height === traitValuesArr[i]) {
return true;
}
else {
return false;
}
})
}
}
let weight = [];
for (let i = 0; i < chosenTraitsArr.length; i++){
if (chosenTraitsArr[i] === "weight") {
weight = people.filter(function(list) {
if (list.weight === traitValuesArr[i]) {
return true;
}
else {
return false;
}
})
}
}
let eyecolor = [];
for (let i = 0; i < chosenTraitsArr.length; i++){
if (chosenTraitsArr[i] === "eyecolor") {
eyecolor = people.filter(function(list) {
if (list.eyeColor === traitValuesArr[i]) {
return true;
}
else {
return false;
}
})
}
}
let occupation = [];
for (let i = 0; i < chosenTraitsArr.length; i++){
if (chosenTraitsArr[i] === "occupation") {
occupation = people.filter(function(list) {
if (list.occupation === traitValuesArr[i]) {
return true;
}
else {
return false;
}
})
}
}
if (gender.length > 0) {
for (let i = 0; i < gender.length; i++)
searchResults.push(gender[i].firstName + " " + gender[i].lastName )
}
if (height.length > 0) {
for (let i = 0; i < height.length; i++)
searchResults.push(height[i].firstName + " " + height[i].lastName )
}
if (weight.length > 0) {
for (let i = 0; i < weight.length; i++)
searchResults.push(weight[i].firstName + " " + weight[i].lastName )
}
if (eyecolor.length > 0) {
for (let i = 0; i < eyecolor.length; i++)
searchResults.push(eyecolor[i].firstName + " " + eyecolor[i].lastName )
}
if (occupation.length > 0) {
for (let i = 0; i < occupation.length; i++)
searchResults.push(occupation[i].firstName + " " + occupation[i].lastName )
}
function findRepeats(arra1) {
var object = {};
var result = [];
arra1.forEach(function (item) {
if(!object[item])
object[item] = 0;
object[item] += 1;
})
for (var prop in object) {
if(object[prop] >= chosenTraitsArr.length) {
result.push(prop);
}
}
if (result.length >= 1) {
let verticalList = "";
if (result.length >= 1) { //Displays all the results in a vertical list with a new person for each row to make it easier for the user to read
for (let i = 0; i < result.length; i++) {
verticalList += result[i] + "\n";
}
}
else {
verticalList = "Sorry. No one was found that meets that criteria."
}
return verticalList;
}
}
alert("The following people met your search criteria: " + "\n" + findRepeats(searchResults));
return app(people);
}
/*======================================================================*/
function searchByName(people){
let firstName = promptFor("What is the person's first name?", chars);
let lastName = promptFor("What is the person's last name?", chars);
let foundPerson = people.filter(function(person){
if(person.firstName.toLowerCase() === firstName.toLowerCase() && person.lastName.toLowerCase() === lastName.toLowerCase()){
return true;
}
else{
return false;
}
})
return foundPerson;
}
// alerts a list of people
function displayPeople(people){
alert(people.map(function(person){
return person.firstName + " " + person.lastName;
}).join("\n"));
}
function displayPerson(person){
// print all of the information about a person:
// height, weight, age, name, occupation, eye color.
let age = calculate_age(person[0].dob);
let personInfo = "First Name: " + person[0].firstName + "\n";
personInfo += "Last Name: " + person[0].lastName + "\n";
personInfo += "Height: " + person[0].height + "\n";
personInfo += "Weight: " + person[0].weight + "\n";
personInfo += "Age: " + age + "\n";
personInfo += "Eye Color: " + person[0].eyeColor + "\n";
personInfo += "Occupation: " + person[0].occupation + "\n";
alert(personInfo);
}
//Function to find and dispay all descendants of the person searched for
let listDescendants = [];
function displayDescendants(person, people, counter) {
let descendants = [];
for (let i = 0; i < person.length; i++) { //Loop through whoever is in the "people" array to find anyone in the dataset who's ID matches either of the IDs in the "parents" array and returns a new array "descendants"
descendants = people.filter(function(list) {
if (person[i].id === list.parents[0] || person[i].id === list.parents[1]) {
return true;
}
else{
return false;
}
})
}
for (let i = 0; i < descendants.length; i++) { //Loop through anyone that was added to the descendants array and push those values to a new array of listDescendants"
listDescendants.push(descendants[i].firstName + " " + descendants[i].lastName);
}
person = descendants; //Feed the values from descendants into person to overwrite the original values to when the function is called again, it begins by searching for children of the children found in the beginning of the function
if (counter < people.length && person.length >= 1) { //Using recursion, reiterate through the entire dataset with the function to find all descendants
return displayDescendants(person, people, counter + 1);
}
if (listDescendants.length >= 1) { //Displays all the descendants in a vertical list with a new person for each row to make it easier for the user to read
let verticalList = "";
for (let i = 0; i < listDescendants.length; i++) {
verticalList += listDescendants[i] + "\n";
}
alert("The following are all descendants:" + "\n" + verticalList); //Display the vertical list of descencdants found
verticalList = ""; //These values need to be "reset" to empty so if the person does another search, it doesn't add the results from a previous search to the new search results
listDescendants = []
}
else {
alert("No descendants were found.")
}
}
//function to calculate age
function calculate_age(dob) {
let newDOB = Date.parse(dob);
let diff_ms = Date.now() - newDOB;
let age_dt = new Date(diff_ms);
return Math.abs(age_dt.getUTCFullYear() - 1970);
}
// function that prompts and validates user input
function promptFor(question, valid){
do{
var response = prompt(question).trim();
} while(!response || !valid(response));
return response;
}
// helper function to pass into promptFor to validate yes/no answers
function yesNo(input){
return input.toLowerCase() == "yes" || input.toLowerCase() == "no";
}
// helper function to pass in as default promptFor validation
function chars(input){
return true; // default validation only
}
// helper function to prompt and validate the input from the user when choosing which traits to use for search
function promptTraits (input) {
var response = prompt(input).trim().toLowerCase();
var responseArr = response.split(" ");
let valid = "";
if (responseArr.length > 1) {
for (let i = 0; i < responseArr.length; i++) {
if (responseArr[i] === "gender" || responseArr[i] === "height" || responseArr[i] === "weight" || responseArr[i] === "eyecolor" || responseArr[i] === "occupation") {
valid = true;
}
else {
valid = false;
}
}
if (valid === false) {
alert("Your response was invalid. Please choose which traits you would like to search for leaving one space between each trait (i.e.) gender height weight eyecolor occupation");
return promptTraits(input);
}
else {
return response;
}
}
else {
alert("Your response was invalid. Please choose at least 2 traits you would like to search for leaving one space between each trait (i.e. 'gender height weight eyecolor occupation')");
return promptTraits(input);
}
}
function promptGender (input) {
let response = prompt(input).trim().toLowerCase();
let valid;
if (response === "male" || response === "female") {
valid = true;
}
else {
valid = false;
}
if (valid === false) {
alert("Your response was invalid. Please choose either 'male' or 'female'.");
return promptGender(input);
}
else {
return response;
}
}
function promptHeightWeight (input) {
let response = prompt(input).trim().toLowerCase();
let valid;
let regex = new RegExp(/\b(\d)+\b/);
if (regex.test(response)) {
valid = true;
}
else {
valid = false;
}
if (valid === false) {
alert("Your response was invalid. Please choose an integer.");
return promptHeightWeight(input);
}
else {
return response;
}
}
// function that checks for immediate family members - spouse/parents/siblings/children
function immediateFamily(person, people){
//Iterate over every objects' id# to see if it matches the person's parent#
function findParents(person, people){
let foundParent = people.filter(function(parentID){
if(parentID.id === person[0].parents[0] || parentID.id === person[0].parents[1]){
return true;
} else {
return false;
}
})
return foundParent;
}
let parentsFunction = findParents(person, people);
let listOfParents = "";
if(parentsFunction.length > 0){
for(let i=0; i<parentsFunction.length; i++)
listOfParents += parentsFunction[i].firstName + " " + parentsFunction[i].lastName + "\n";
}
//Iterate over every objects' parent# to see if it matches the person's parent#
function findSiblings(person, people){
let foundSibling = people.filter(function(siblingIdentifier){
for (let i = 0; i < siblingIdentifier.parents.length; i++) {
if((person[0].parents[0] === siblingIdentifier.parents[i] || person[0].parents[1] === siblingIdentifier.parents[i]) && person[0].id != siblingIdentifier.id) {
return true;
} else {
return false;
}
}
})
return foundSibling;
}
let siblingsFunction = findSiblings(person, people);
let listOfSiblings ="";
if(siblingsFunction.length > 0){
for(let i=0; i<siblingsFunction.length; i++)
listOfSiblings += siblingsFunction[i].firstName + " " + siblingsFunction[i].lastName + "\n";
} else{
siblingsFunction = "None Found";
}
//Iterate over every objects' id# to see if it matches the person's currentSpouse#
function findSpouse(person, people){
let foundSpouse = people.filter(function(spouseID){
if(spouseID.id === person[0].currentSpouse){
return true;
} else {
return false;
}
})
return foundSpouse[0].firstName + " " + foundSpouse[0].lastName;
}
//A function to call all the above functions
function displayImmediateFamily(person, people){
let printParents = listOfParents;
let printSiblings = listOfSiblings;
let printSpouse = findSpouse(person, people);
let familyAlert = alert("Parents: \n" + printParents + "\nSiblings: \n" + printSiblings + "\nSpouse: " + printSpouse);
}
//Now call everything
let familyInformation = displayImmediateFamily(person, people);
}