We use cookies to enhance your experience on the site
CodeWorlds

Basic Array Methods in JavaScript

Welcome back to Jurassic Park! In the previous module, we learned the basics of arrays in JavaScript. Now we will dive into the basic array methods that are essential for everyday data work. These methods allow you to add, remove, and manipulate elements in arrays, which is crucial for managing the dinosaur inventory, planning feedings, and organizing park staff.

Modifying Arrays - Mutating Methods

First, let's look at methods that modify the original array. These are called mutating methods.

1. push() - Adding Elements to the End of an Array

The

push()
method adds one or more elements to the end of an array and returns the new length of the array:

1// Managing dinosaur species in our enclosure
2const dinoEnclosure = ["T-Rex", "Velociraptor"];
3
4// Adding a new dinosaur species
5dinoEnclosure.push("Dilophosaurus");
6console.log(dinoEnclosure); // ["T-Rex", "Velociraptor", "Dilophosaurus"]
7
8// Adding several species at once
9const newLength = dinoEnclosure.push("Gallimimus", "Compsognathus");
10console.log(dinoEnclosure);
11// ["T-Rex", "Velociraptor", "Dilophosaurus", "Gallimimus", "Compsognathus"]
12console.log(`Current number of species in enclosure: ${newLength}`); // 5

When to use

push()
:

  • When you need to add element(s) to the end of an array
  • When you want to track the new array length after adding elements
  • When the order of elements matters and the new element should go at the end

2. pop() - Removing the Last Element

The

pop()
method removes the last element from an array and returns that element:

1// List of dinosaurs in our enclosure
2const dinoEnclosure = ["T-Rex", "Velociraptor", "Dilophosaurus", "Compsognathus"];
3
4// Moving the last dinosaur to a new enclosure
5const removedDino = dinoEnclosure.pop();
6console.log(`Moved dinosaur: ${removedDino}`); // "Compsognathus"
7console.log(`Remaining dinosaurs: ${dinoEnclosure}`); // ["T-Rex", "Velociraptor", "Dilophosaurus"]
8
9// We can continue removing
10const anotherRemovedDino = dinoEnclosure.pop();
11console.log(`Moved another dinosaur: ${anotherRemovedDino}`); // "Dilophosaurus"
12console.log(`Current enclosure contents: ${dinoEnclosure}`); // ["T-Rex", "Velociraptor"]

When to use

pop()
:

  • When you need to remove the last element from an array
  • When you need to retrieve the value of the removed element
  • When implementing stack data structures (LIFO - Last In, First Out)

3. unshift() - Adding Elements to the Beginning

The

unshift()
method adds one or more elements to the beginning of an array and returns the new length of the array:

1// Queue of dinosaurs waiting for examination
2const dinoQueue = ["Velociraptor", "Triceratops"];
3
4// Priority addition of T-Rex to the front of the queue
5dinoQueue.unshift("T-Rex");
6console.log(`Current queue: ${dinoQueue}`); // ["T-Rex", "Velociraptor", "Triceratops"]
7
8// Adding several dinosaurs at once to the front
9const newQueueSize = dinoQueue.unshift("Brachiosaurus", "Stegosaurus");
10console.log(`Current queue: ${dinoQueue}`);
11// ["Brachiosaurus", "Stegosaurus", "T-Rex", "Velociraptor", "Triceratops"]
12console.log(`Number of dinosaurs in queue: ${newQueueSize}`); // 5

When to use

unshift()
:

  • When you want to add an element to the beginning of an array
  • When implementing priority queues where higher-priority elements go to the front
  • When you need to track the new array length

4. shift() - Removing the First Element

The

shift()
method removes the first element from an array and returns that element:

1// Queue of dinosaurs waiting for examination
2const dinoQueue = ["T-Rex", "Velociraptor", "Triceratops", "Stegosaurus"];
3
4// Getting the first dinosaur for examination
5const nextDino = dinoQueue.shift();
6console.log(`Examining dinosaur: ${nextDino}`); // "T-Rex"
7console.log(`Remaining queue: ${dinoQueue}`); // ["Velociraptor", "Triceratops", "Stegosaurus"]
8
9// Processing the next dinosaur
10const anotherDino = dinoQueue.shift();
11console.log(`Next dinosaur for examination: ${anotherDino}`); // "Velociraptor"
12console.log(`Current queue state: ${dinoQueue}`); // ["Triceratops", "Stegosaurus"]

When to use

shift()
:

  • When you need to remove and retrieve the first element of an array
  • When implementing queues (FIFO - First In, First Out)
  • When processing elements in the order they were added

5. splice() - Modifying Elements at Any Position

The

splice()
method changes the contents of an array by removing, replacing, or adding elements. It is extremely versatile because it allows modification of the array at any position.

Basic syntax:

array.splice(startIndex, deleteCount, item1, item2, ...)
:

  • startIndex
    : the index at which to start the change
  • deleteCount
    : the number of elements to remove
  • item1, item2, ...
    : (optional) elements to add

5.1. Removing Elements with splice()

1// List of dinosaur species in the park
2const dinosaurs = ["T-Rex", "Velociraptor", "Triceratops", "Stegosaurus", "Brachiosaurus"];
3
4// Remove 2 elements starting from index 1 (the second element)
5const removedDinos = dinosaurs.splice(1, 2);
6console.log(`Removed dinosaurs: ${removedDinos}`); // ["Velociraptor", "Triceratops"]
7console.log(`Remaining dinosaurs: ${dinosaurs}`); // ["T-Rex", "Stegosaurus", "Brachiosaurus"]

5.2. Replacing Elements with splice()

1// List of dinosaur species
2const dinosaurs = ["T-Rex", "Dilophosaurus", "Triceratops", "Stegosaurus"];
3
4// Replace Dilophosaurus with Velociraptor
5const replaced = dinosaurs.splice(1, 1, "Velociraptor");
6console.log(`Replaced dinosaur: ${replaced}`); // ["Dilophosaurus"]
7console.log(`Current list: ${dinosaurs}`); // ["T-Rex", "Velociraptor", "Triceratops", "Stegosaurus"]
8
9// Replace multiple elements at once
10dinosaurs.splice(2, 2, "Brachiosaurus", "Ankylosaurus", "Parasaurolophus");
11console.log(`New roster: ${dinosaurs}`);
12// ["T-Rex", "Velociraptor", "Brachiosaurus", "Ankylosaurus", "Parasaurolophus"]

5.3. Adding Elements Without Removing

1// List of dinosaur species
2const dinosaurs = ["T-Rex", "Velociraptor"];
3
4// Add new species at index 1 (between T-Rex and Velociraptor)
5dinosaurs.splice(1, 0, "Dilophosaurus", "Compsognathus");
6console.log(dinosaurs); // ["T-Rex", "Dilophosaurus", "Compsognathus", "Velociraptor"]

When to use

splice()
:

  • When you need to modify an array at a specific position, not just at the end or beginning
  • When you need to remove and/or add elements simultaneously
  • When you want to replace a section of an array with new values

6. sort() - Sorting an Array

The

sort()
method sorts the elements of an array in place and returns the sorted array:

1// List of dinosaurs for feeding
2const feedingList = ["Velociraptor", "T-Rex", "Dilophosaurus", "Gallimimus", "Compsognathus"];
3
4// Alphabetical sorting
5feedingList.sort();
6console.log(`Feeding list (alphabetical): ${feedingList}`);
7// ["Compsognathus", "Dilophosaurus", "Gallimimus", "T-Rex", "Velociraptor"]
8
9// Array with dinosaur sizes (in cm)
10const dinoSizes = [1200, 300, 800, 2000, 40];
11
12// Default sort treats numbers as strings - this won't work correctly!
13dinoSizes.sort();
14console.log("Incorrectly sorted sizes:", dinoSizes);
15// Probably: [1200, 2000, 300, 40, 800] - incorrect!
16
17// Correct number sorting with a compare function
18dinoSizes.sort((a, b) => a - b);
19console.log("Correctly sorted sizes (ascending):", dinoSizes);
20// [40, 300, 800, 1200, 2000]
21
22// Descending sort
23dinoSizes.sort((a, b) => b - a);
24console.log("Sizes sorted descending:", dinoSizes);
25// [2000, 1200, 800, 300, 40]

Sorting Objects

1// Dinosaur data for feeding
2const dinosaurs = [
3  { name: "T-Rex", weight: 7000, priority: 1 },
4  { name: "Velociraptor", weight: 100, priority: 2 },
5  { name: "Triceratops", weight: 9000, priority: 3 },
6  { name: "Gallimimus", weight: 450, priority: 4 }
7];
8
9// Sort by feeding priority
10dinosaurs.sort((a, b) => a.priority - b.priority);
11console.log("Feeding order by priority:");
12dinosaurs.forEach(dino => console.log(`${dino.name} (priority: ${dino.priority})`));
13
14// Sort by weight (heaviest first)
15dinosaurs.sort((a, b) => b.weight - a.weight);
16console.log("\nOrder by weight (heaviest first):");
17dinosaurs.forEach(dino => console.log(`${dino.name} (${dino.weight} kg)`));
18
19// Sort alphabetically by name
20dinosaurs.sort((a, b) => a.name.localeCompare(b.name));
21console.log("\nDinosaurs alphabetically:");
22dinosaurs.forEach(dino => console.log(`${dino.name}`));

The

sort()
method takes an optional compare function that should return:

  • A negative value if a should be before b
  • Zero if a and b are equivalent in terms of sorting
  • A positive value if a should be after b

When to use

sort()
:

  • When you need to order array elements by a specific criterion
  • When working with lists that must be presented in a specific order
  • When implementing sorting functionality in an application

7. reverse() - Reversing Array Order

The

reverse()
method reverses the order of elements in an array and returns the reversed array:

1// List of dinosaurs from oldest to youngest
2const dinosaursByAge = ["Brachiosaurus", "Stegosaurus", "Triceratops", "Velociraptor", "T-Rex"];
3
4// Reverse the order to get youngest to oldest
5dinosaursByAge.reverse();
6console.log("From youngest to oldest:", dinosaursByAge);
7// ["T-Rex", "Velociraptor", "Triceratops", "Stegosaurus", "Brachiosaurus"]
8
9// Often used in combination with sort()
10const dinoHeights = [500, 900, 200, 1200, 350];
11// Descending sort by sorting ascending + reversing
12dinoHeights.sort((a, b) => a - b).reverse();
13console.log("Heights descending:", dinoHeights);
14// [1200, 900, 500, 350, 200]

When to use

reverse()
:

  • When you need to reverse the order of elements in an array
  • When you want to switch from ascending to descending order (or vice versa) after sorting
  • When implementing a "reverse order" feature in a user interface

8. fill() - Filling an Array with a Value

The

fill()
method fills all elements of an array from a start index to an end index (not including) with a specified value:

1// Preparing an array for dinosaur temperature readings (10 readings)
2const temperatures = new Array(10);
3
4// Fill with a default value (38.5 degrees Celsius)
5temperatures.fill(38.5);
6console.log(`Default temperatures: ${temperatures}`);
7// [38.5, 38.5, 38.5, 38.5, 38.5, 38.5, 38.5, 38.5, 38.5, 38.5]
8
9// Fill only part of the array
10temperatures.fill(39.2, 2, 5); // From index 2 (inclusive) to 5 (exclusive)
11console.log(`Updated temperatures: ${temperatures}`);
12// [38.5, 38.5, 39.2, 39.2, 39.2, 38.5, 38.5, 38.5, 38.5, 38.5]
13
14// Using with a new array and negative indices (counted from the end)
15const feedingSchedule = new Array(7).fill("Standard");
16feedingSchedule.fill("Extra portion", -3); // Last 3 days
17console.log(`Weekly feeding plan: ${feedingSchedule}`);
18// ["Standard", "Standard", "Standard", "Standard", "Extra portion", "Extra portion", "Extra portion"]

When to use

fill()
:

  • When creating a new array and need to fill it with a specific initial value
  • When you need to replace all or some values in an existing array
  • When initializing arrays to store data with default values

Applying Basic Array Methods in Practice

Now let's combine the methods we've learned to solve more practical scenarios in our Jurassic Park:

Example 1: Dinosaur Food Management System

1// Dinosaur food management system
2const feedingSystem = {
3  // System state
4  foodInventory: [],
5  feedingQueue: [],
6  feedingHistory: [],
7
8  // Adding a new food supply
9  addFoodSupply: function(type, quantity, expirationDate) {
10    const supply = { type, quantity, expirationDate, addedOn: new Date() };
11    this.foodInventory.push(supply);
12
13    // Sort by expiration date (soonest first)
14    this.foodInventory.sort((a, b) =>
15      new Date(a.expirationDate) - new Date(b.expirationDate)
16    );
17
18    console.log(`Added ${quantity}kg of "${type}" food to supplies.`);
19    return supply;
20  },
21
22  // Adding a dinosaur to the feeding queue
23  scheduleDinoFeeding: function(dinoId, dinoName, foodType, quantity, priority) {
24    const feedingRequest = {
25      dinoId,
26      dinoName,
27      foodType,
28      quantity,
29      priority,
30      scheduledAt: new Date()
31    };
32
33    if (priority === "high") {
34      // Add to the front of the queue
35      this.feedingQueue.unshift(feedingRequest);
36    } else {
37      // Add to the end of the queue
38      this.feedingQueue.push(feedingRequest);
39    }
40
41    console.log(`Scheduled feeding for ${dinoName} (priority: ${priority})`);
42    return this.feedingQueue.length;
43  },
44
45  // Getting the next dinosaur to feed
46  getNextDinoToFeed: function() {
47    if (this.feedingQueue.length === 0) {
48      console.log("All dinosaurs fed. Queue empty.");
49      return null;
50    }
51
52    const nextFeeding = this.feedingQueue.shift();
53    console.log(`Next to feed: ${nextFeeding.dinoName}`);
54    return nextFeeding;
55  },
56
57  // Dispensing food from the warehouse
58  dispenseFoodForDino: function(dinoFeeding) {
59    const { foodType, quantity, dinoName } = dinoFeeding;
60
61    // Search for the appropriate food supply
62    let remainingQuantity = quantity;
63    const usedSupplies = [];
64
65    // Iterate from the oldest supply (expires soonest)
66    for (let i = 0; i < this.foodInventory.length && remainingQuantity > 0; i++) {
67      const supply = this.foodInventory[i];
68
69      if (supply.type === foodType && supply.quantity > 0) {
70        // How much we can take from this supply
71        const amountToTake = Math.min(remainingQuantity, supply.quantity);
72        supply.quantity -= amountToTake;
73        remainingQuantity -= amountToTake;
74
75        usedSupplies.push({
76          type: supply.type,
77          amount: amountToTake,
78          expirationDate: supply.expirationDate
79        });
80
81        // If the supply is empty, remove it from inventory
82        if (supply.quantity === 0) {
83          this.foodInventory.splice(i, 1);
84          i--; // Adjust index after removing element
85        }
86      }
87    }
88
89    // Add record to feeding history
90    const feedingRecord = {
91      ...dinoFeeding,
92      fedAt: new Date(),
93      suppliesUsed: usedSupplies,
94      fullyFed: remainingQuantity === 0
95    };
96
97    this.feedingHistory.push(feedingRecord);
98
99    if (remainingQuantity > 0) {
100      console.log(`WARNING: Missing ${remainingQuantity}kg of "${foodType}" food for ${dinoName}!`);
101      return false;
102    }
103
104    console.log(`Fed ${dinoName} using ${quantity}kg of "${foodType}" food.`);
105    return feedingRecord;
106  },
107
108  // Performing a full feeding cycle
109  processFeedingCycle: function(maxFeedings = 5) {
110    console.log("=== STARTING FEEDING CYCLE ===");
111    let feedingsProcessed = 0;
112
113    // Process a specified number of feedings or until the queue is empty
114    while (feedingsProcessed < maxFeedings && this.feedingQueue.length > 0) {
115      const nextDino = this.getNextDinoToFeed();
116
117      if (nextDino) {
118        const result = this.dispenseFoodForDino(nextDino);
119
120        if (!result) {
121          // If feeding failed, move the dinosaur to the end of the queue
122          this.feedingQueue.push({
123            ...nextDino,
124            priority: "high", // Raise priority for unfed dinosaur
125            scheduledAt: new Date()
126          });
127          console.log(`${nextDino.dinoName} moved to end of queue with high priority.`);
128        }
129
130        feedingsProcessed++;
131      }
132    }
133
134    console.log(`=== FEEDING CYCLE COMPLETE (processed: ${feedingsProcessed}) ===`);
135    console.log(`Remaining in queue: ${this.feedingQueue.length} dinosaurs`);
136    return feedingsProcessed;
137  },
138
139  // Reporting inventory status
140  reportInventoryStatus: function() {
141    console.log("=== INVENTORY STATUS REPORT ===");
142
143    if (this.foodInventory.length === 0) {
144      console.log("Warehouse is empty! Order new food supplies!");
145      return { isEmpty: true, totalQuantity: 0, types: [] };
146    }
147
148    // Group supplies by type
149    const inventory = this.foodInventory.reduce((acc, supply) => {
150      if (!acc[supply.type]) {
151        acc[supply.type] = 0;
152      }
153      acc[supply.type] += supply.quantity;
154      return acc;
155    }, {});
156
157    // Calculate total quantity
158    const totalQuantity = Object.values(inventory).reduce((sum, qty) => sum + qty, 0);
159
160    console.log(`Total food supply: ${totalQuantity}kg`);
161    Object.entries(inventory).forEach(([type, qty]) => {
162      console.log(`- ${type}: ${qty}kg`);
163    });
164
165    // Check supplies expiring soon (within 3 days)
166    const today = new Date();
167    const threeDaysLater = new Date(today);
168    threeDaysLater.setDate(today.getDate() + 3);
169
170    const expiringSupplies = this.foodInventory.filter(supply =>
171      new Date(supply.expirationDate) <= threeDaysLater
172    );
173
174    if (expiringSupplies.length > 0) {
175      console.log("\nSupplies expiring within 3 days:");
176      expiringSupplies.forEach(supply => {
177        console.log(`- ${supply.quantity}kg ${supply.type} (expires: ${supply.expirationDate})`);
178      });
179    }
180
181    return {
182      isEmpty: false,
183      totalQuantity,
184      types: Object.keys(inventory),
185      inventory,
186      expiringSupplies
187    };
188  }
189};
190
191// System demonstration
192console.log("=== FOOD MANAGEMENT SYSTEM DEMONSTRATION ===");
193
194// 1. Adding food supplies
195feedingSystem.addFoodSupply("Meat", 500, "2023-07-15");
196feedingSystem.addFoodSupply("Plants", 800, "2023-07-10");
197feedingSystem.addFoodSupply("Fish", 200, "2023-07-05");
198feedingSystem.addFoodSupply("Meat", 300, "2023-07-20");
199
200// 2. Scheduling feedings
201feedingSystem.scheduleDinoFeeding("TRX-01", "Rex", "Meat", 150, "high");
202feedingSystem.scheduleDinoFeeding("VEL-02", "Blue", "Meat", 50, "normal");
203feedingSystem.scheduleDinoFeeding("TRCP-03", "Trixie", "Plants", 120, "normal");
204feedingSystem.scheduleDinoFeeding("BRCH-04", "Bronty", "Plants", 250, "normal");
205feedingSystem.scheduleDinoFeeding("STEG-05", "Spike", "Plants", 100, "high");
206
207// 3. Inventory status report before feeding
208feedingSystem.reportInventoryStatus();
209
210// 4. Processing feeding cycle
211feedingSystem.processFeedingCycle(3); // Process only 3 feedings
212
213// 5. Check inventory status after feeding
214feedingSystem.reportInventoryStatus();
215
216// 6. Complete the feeding cycle
217feedingSystem.processFeedingCycle(5); // Process remaining feedings
218
219// 7. Check inventory status after full cycle
220feedingSystem.reportInventoryStatus();

Example 2: Park Staff Team Management

1// Jurassic Park staff team management system
2const staffManagementSystem = {
3  // System data
4  departments: [
5    { id: "OPS", name: "Operations" },
6    { id: "SCI", name: "Scientific Research" },
7    { id: "SEC", name: "Security" },
8    { id: "VET", name: "Veterinary" },
9    { id: "MAINT", name: "Maintenance" }
10  ],
11  staff: [],
12  teams: [],
13
14  // Adding a new employee
15  addStaffMember: function(name, role, skills, departmentId) {
16    // Check if department exists
17    const department = this.departments.find(dept => dept.id === departmentId);
18    if (!department) {
19      console.log(`Error: Department with ID "${departmentId}" does not exist.`);
20      return null;
21    }
22
23    // Generate employee ID
24    const id = `${departmentId}-${(this.staff.length + 1).toString().padStart(3, '0')}`;
25
26    const staffMember = {
27      id,
28      name,
29      role,
30      skills: Array.isArray(skills) ? skills : [skills],
31      departmentId,
32      departmentName: department.name,
33      hireDate: new Date().toISOString().split('T')[0]
34    };
35
36    this.staff.push(staffMember);
37    console.log(`Added employee: ${name} (${role}) to department ${department.name}`);
38
39    return staffMember;
40  },
41
42  // Creating a new team
43  createTeam: function(name, mission, leaderId) {
44    // Check if leader exists
45    const leader = this.staff.find(person => person.id === leaderId);
46    if (!leader) {
47      console.log(`Error: Employee with ID "${leaderId}" does not exist.`);
48      return null;
49    }
50
51    const teamId = `TEAM-${(this.teams.length + 1).toString().padStart(3, '0')}`;
52
53    const team = {
54      id: teamId,
55      name,
56      mission,
57      createdAt: new Date().toISOString().split('T')[0],
58      leaderId,
59      leaderName: leader.name,
60      members: [leaderId],
61      status: "active"
62    };
63
64    this.teams.push(team);
65    console.log(`Created team: ${name} (mission: ${mission}), leader: ${leader.name}`);
66
67    return team;
68  },
69
70  // Adding an employee to a team
71  addMemberToTeam: function(teamId, memberId) {
72    // Find team
73    const teamIndex = this.teams.findIndex(team => team.id === teamId);
74    if (teamIndex === -1) {
75      console.log(`Error: Team with ID "${teamId}" does not exist.`);
76      return false;
77    }
78
79    // Find employee
80    const member = this.staff.find(person => person.id === memberId);
81    if (!member) {
82      console.log(`Error: Employee with ID "${memberId}" does not exist.`);
83      return false;
84    }
85
86    // Check if employee is already in the team
87    if (this.teams[teamIndex].members.includes(memberId)) {
88      console.log(`${member.name} is already a member of team ${this.teams[teamIndex].name}.`);
89      return false;
90    }
91
92    // Add employee to team
93    this.teams[teamIndex].members.push(memberId);
94    console.log(`Added ${member.name} to team ${this.teams[teamIndex].name}.`);
95
96    return true;
97  },
98
99  // Removing an employee from a team
100  removeMemberFromTeam: function(teamId, memberId) {
101    // Find team
102    const teamIndex = this.teams.findIndex(team => team.id === teamId);
103    if (teamIndex === -1) {
104      console.log(`Error: Team with ID "${teamId}" does not exist.`);
105      return false;
106    }
107
108    // Check if employee is the leader
109    if (this.teams[teamIndex].leaderId === memberId) {
110      console.log(`Error: Cannot remove the team leader. Change the leader first.`);
111      return false;
112    }
113
114    // Find employee index in the team
115    const memberIndex = this.teams[teamIndex].members.indexOf(memberId);
116    if (memberIndex === -1) {
117      console.log(`Employee is not a member of team ${this.teams[teamIndex].name}.`);
118      return false;
119    }
120
121    // Find employee for informational purposes
122    const member = this.staff.find(person => person.id === memberId);
123
124    // Remove employee from team
125    this.teams[teamIndex].members.splice(memberIndex, 1);
126    console.log(`Removed ${member ? member.name : memberId} from team ${this.teams[teamIndex].name}.`);
127
128    return true;
129  },
130
131  // Changing team leader
132  changeTeamLeader: function(teamId, newLeaderId) {
133    // Find team
134    const teamIndex = this.teams.findIndex(team => team.id === teamId);
135    if (teamIndex === -1) {
136      console.log(`Error: Team with ID "${teamId}" does not exist.`);
137      return false;
138    }
139
140    // Check if new leader exists
141    const newLeader = this.staff.find(person => person.id === newLeaderId);
142    if (!newLeader) {
143      console.log(`Error: Employee with ID "${newLeaderId}" does not exist.`);
144      return false;
145    }
146
147    // Check if new leader is a team member
148    if (!this.teams[teamIndex].members.includes(newLeaderId)) {
149      // Add new leader to team if not already a member
150      this.teams[teamIndex].members.push(newLeaderId);
151      console.log(`${newLeader.name} was added to the team as the new leader.`);
152    }
153
154    // Save old leader info for the message
155    const oldLeaderId = this.teams[teamIndex].leaderId;
156    const oldLeader = this.staff.find(person => person.id === oldLeaderId);
157
158    // Update leader
159    this.teams[teamIndex].leaderId = newLeaderId;
160    this.teams[teamIndex].leaderName = newLeader.name;
161
162    console.log(`Team ${this.teams[teamIndex].name} leader changed from ${oldLeader.name} to ${newLeader.name}.`);
163    return true;
164  },
165
166  // Deactivating a team
167  deactivateTeam: function(teamId, reason) {
168    // Find team
169    const teamIndex = this.teams.findIndex(team => team.id === teamId);
170    if (teamIndex === -1) {
171      console.log(`Error: Team with ID "${teamId}" does not exist.`);
172      return false;
173    }
174
175    // Save state before modification
176    const teamName = this.teams[teamIndex].name;
177
178    // Update team status
179    this.teams[teamIndex].status = "inactive";
180    this.teams[teamIndex].deactivatedAt = new Date().toISOString().split('T')[0];
181    this.teams[teamIndex].deactivationReason = reason || "Unspecified";
182
183    console.log(`Team ${teamName} has been deactivated. Reason: ${this.teams[teamIndex].deactivationReason}`);
184    return true;
185  },
186
187  // Generating a teams report
188  generateTeamsReport: function(includeInactive = false) {
189    console.log("=== JURASSIC PARK TEAMS REPORT ===");
190
191    // Filter teams by status if not including inactive
192    const teamsToReport = includeInactive
193      ? this.teams
194      : this.teams.filter(team => team.status === "active");
195
196    if (teamsToReport.length === 0) {
197      console.log("No teams to display.");
198      return { teams: [] };
199    }
200
201    // Prepare report data
202    const teamsData = teamsToReport.map(team => {
203      // Get full member information
204      const memberDetails = team.members.map(memberId => {
205        const member = this.staff.find(person => person.id === memberId);
206        return member ? {
207          id: member.id,
208          name: member.name,
209          role: member.role,
210          isLeader: memberId === team.leaderId
211        } : { id: memberId, name: "Unknown", role: "Unknown", isLeader: false };
212      });
213
214      return {
215        id: team.id,
216        name: team.name,
217        mission: team.mission,
218        status: team.status,
219        memberCount: team.members.length,
220        leader: this.staff.find(person => person.id === team.leaderId),
221        members: memberDetails,
222        createdAt: team.createdAt,
223        deactivatedAt: team.deactivatedAt,
224        deactivationReason: team.deactivationReason
225      };
226    });
227
228    // Sort teams - active first, then by creation date
229    teamsData.sort((a, b) => {
230      if (a.status !== b.status) {
231        return a.status === "active" ? -1 : 1;
232      }
233      return new Date(b.createdAt) - new Date(a.createdAt);
234    });
235
236    // Display summary
237    console.log(`Number of teams: ${teamsData.length}`);
238    console.log(`Active teams: ${teamsData.filter(t => t.status === "active").length}`);
239    if (includeInactive) {
240      console.log(`Inactive teams: ${teamsData.filter(t => t.status === "inactive").length}`);
241    }
242
243    // Display details for each team
244    teamsData.forEach(team => {
245      console.log(`\n${team.id}: ${team.name} (Status: ${team.status})`);
246      console.log(`Mission: ${team.mission}`);
247      console.log(`Leader: ${team.leader ? team.leader.name : 'None'} (${team.leader ? team.leader.role : ''})`);
248      console.log(`Number of members: ${team.memberCount}`);
249      console.log("Members:");
250      team.members.forEach(member => {
251        console.log(`  - ${member.name} (${member.role})${member.isLeader ? ' [LEADER]' : ''}`);
252      });
253
254      if (team.status === "inactive") {
255        console.log(`Deactivated: ${team.deactivatedAt}`);
256        console.log(`Reason: ${team.deactivationReason}`);
257      }
258    });
259
260    return { teams: teamsData };
261  },
262
263  // Reorganizing teams
264  reorganizeTeams: function(fromTeamId, toTeamId, memberIds, dissolveSourceTeam = false) {
265    // Check if teams exist
266    const fromTeamIndex = this.teams.findIndex(team => team.id === fromTeamId);
267    const toTeamIndex = this.teams.findIndex(team => team.id === toTeamId);
268
269    if (fromTeamIndex === -1 || toTeamIndex === -1) {
270      console.log(`Error: One or both teams do not exist.`);
271      return false;
272    }
273
274    // Check if teams are active
275    if (this.teams[fromTeamIndex].status !== "active" || this.teams[toTeamIndex].status !== "active") {
276      console.log(`Error: Teams must be active to reorganize them.`);
277      return false;
278    }
279
280    // If no specific members specified, transfer all (except leader)
281    const membersToMove = memberIds ||
282      this.teams[fromTeamIndex].members.filter(id => id !== this.teams[fromTeamIndex].leaderId);
283
284    // Transfer members
285    for (const memberId of membersToMove) {
286      // Check if employee is part of the source team
287      if (!this.teams[fromTeamIndex].members.includes(memberId)) {
288        console.log(`Error: Employee with ID ${memberId} is not a member of the source team.`);
289        continue;
290      }
291
292      // Check if employee is the leader (if we don't want to transfer everyone)
293      if (memberIds && memberId === this.teams[fromTeamIndex].leaderId) {
294        console.log(`Cannot transfer team leader. Change the leader first.`);
295        continue;
296      }
297
298      // Check if employee is already part of the target team
299      if (this.teams[toTeamIndex].members.includes(memberId)) {
300        console.log(`Employee with ID ${memberId} is already a member of the target team.`);
301        continue;
302      }
303
304      // Remove from original team
305      const fromIndex = this.teams[fromTeamIndex].members.indexOf(memberId);
306      this.teams[fromTeamIndex].members.splice(fromIndex, 1);
307
308      // Add to new team
309      this.teams[toTeamIndex].members.push(memberId);
310
311      // Find employee name for logs
312      const member = this.staff.find(person => person.id === memberId);
313      console.log(`Transferred ${member ? member.name : memberId} from team ${this.teams[fromTeamIndex].name} to ${this.teams[toTeamIndex].name}`);
314    }
315
316    // If chosen to dissolve source team and no members left
317    if (dissolveSourceTeam || this.teams[fromTeamIndex].members.length === 0) {
318      this.deactivateTeam(fromTeamId, "Reorganization - team transferred");
319    }
320
321    return true;
322  }
323};
324
325// Staff team management system demonstration
326console.log("=== STAFF TEAM MANAGEMENT SYSTEM DEMONSTRATION ===");
327
328// 1. Adding employees
329const owen = staffManagementSystem.addStaffMember("Owen Grady", "Dinosaur Trainer", ["Animal behavior", "Training", "First aid"], "OPS");
330const claire = staffManagementSystem.addStaffMember("Claire Dearing", "Operations Director", ["Management", "Marketing", "Administration"], "OPS");
331const dr_wu = staffManagementSystem.addStaffMember("Dr. Henry Wu", "Chief Geneticist", ["Genetics", "Bioengineering", "Cloning"], "SCI");
332const barry = staffManagementSystem.addStaffMember("Barry", "Assistant Trainer", ["Training", "Animal care"], "OPS");
333const lowery = staffManagementSystem.addStaffMember("Lowery Cruthers", "Systems Technician", ["IT", "Monitoring", "Communication"], "SEC");
334const vivian = staffManagementSystem.addStaffMember("Vivian Krill", "Security Coordinator", ["Security", "Communication", "Crisis management"], "SEC");
335const muldoon = staffManagementSystem.addStaffMember("Robert Muldoon", "Security Specialist", ["Firearms", "Security", "Tracking"], "SEC");
336const malcolm = staffManagementSystem.addStaffMember("Dr. Ian Malcolm", "Mathematician", ["Chaos theory", "Risk analysis", "Modeling"], "SCI");
337const sattler = staffManagementSystem.addStaffMember("Dr. Ellie Sattler", "Paleobotanist", ["Botany", "Paleontology", "Ecology"], "SCI");
338const harding = staffManagementSystem.addStaffMember("Dr. Gerry Harding", "Veterinarian", ["Veterinary medicine", "Zoology", "Medicine"], "VET");
339
340// 2. Creating teams
341const raptorTeam = staffManagementSystem.createTeam("Velociraptor Team", "Training and care of Velociraptors", owen.id);
342staffManagementSystem.addMemberToTeam(raptorTeam.id, barry.id);
343
344const securityTeam = staffManagementSystem.createTeam("Security Team", "Ensuring park safety", muldoon.id);
345staffManagementSystem.addMemberToTeam(securityTeam.id, vivian.id);
346staffManagementSystem.addMemberToTeam(securityTeam.id, lowery.id);
347
348const scienceTeam = staffManagementSystem.createTeam("Science Team", "Scientific research and development", dr_wu.id);
349staffManagementSystem.addMemberToTeam(scienceTeam.id, malcolm.id);
350staffManagementSystem.addMemberToTeam(scienceTeam.id, sattler.id);
351
352// 3. Teams report
353staffManagementSystem.generateTeamsReport();
354
355// 4. Team reorganization
356console.log("\n=== TEAM REORGANIZATION ===");
357
358// Creating a new crisis management team
359const crisisTeam = staffManagementSystem.createTeam("Crisis Management Team", "Responding to crisis situations", claire.id);
360
361// Transferring members from other teams
362staffManagementSystem.reorganizeTeams(securityTeam.id, crisisTeam.id, [vivian.id]);
363staffManagementSystem.addMemberToTeam(crisisTeam.id, malcolm.id); // Adding Malcolm as risk advisor
364staffManagementSystem.addMemberToTeam(crisisTeam.id, harding.id);  // Adding veterinarian
365
366// Changing science team leader
367staffManagementSystem.changeTeamLeader(scienceTeam.id, sattler.id);
368
369// Deactivating one team
370staffManagementSystem.deactivateTeam(raptorTeam.id, "Project suspended - raptor incident");
371
372// 5. Final teams report (including inactive)
373staffManagementSystem.generateTeamsReport(true);

Summary

In this module, we learned the basic array modification methods in JavaScript:

  1. push() - adds elements to the end of an array
  2. pop() - removes and returns the last element of an array
  3. unshift() - adds elements to the beginning of an array
  4. shift() - removes and returns the first element of an array
  5. splice() - adds, removes, or replaces elements at any position in an array
  6. sort() - sorts array elements
  7. reverse() - reverses the order of array elements
  8. fill() - fills array elements with a specified value

The ability to effectively use these methods is crucial when working with data in JavaScript. They allow you to manage collections, implement data structures (such as stacks and queues), and efficiently manipulate data.

It is worth remembering that the above methods modify the original array (except when you create a copy before applying them). In the next module, we will learn array methods that do not modify the original but return a new array or value.

Go to CodeWorlds