What causes the occurrence of "undefined" after multiple iterations of my code?

I've encountered a curious issue with the code snippet below. Everything seems to be running smoothly except for one thing - after a few iterations, I start getting "undefined" as an output.

You can test this for yourself by running the code multiple times. Initially, you will see the expected output of three random cities, but at some point, "undefined" will pop up. This usually occurs within less than 10 iterations.

I'm puzzled as to why this is happening. What am I overlooking in my code?

var coolWords = ["Amsterdam", "Berlin", "Sofia", "Prague", "Lisbon", "London", "Malaga", "Copenhagen", "Milan"];
    
var newList = [];
    
function niceTripleCombo(coolWords) {
  for (let i = 0; i < 3; i++) {
    var combo = coolWords[Math.floor(Math.random()*coolWords.length)];
    newList.push(" " + combo);
  };
};
    
function iterator(x) {
  if (newList[0] !== newList[1] && newList[1] !== newList[2] && newList[1] !== newList[3]) {
    return newList;
  } else {
    return niceTripleCombo(coolWords);
  }
};
    
    console.log(iterator(niceTripleCombo(coolWords)));

Answer №1

Let's examine this test scenario.

Initially, the function

iterator(niceTripleCombo(coolWords))
is invoked by calling console.log().

Next, the function niceTripleCombo(coolWords) will be executed.

Commencement of niceTripleCombo(coolWords)

Within the for loop,

When i = 0, let's assume we receive newList = [" Milan"]

When i = 1, let's assume we receive newList = [" Milan", " London"]

When i = 2, let's assume we receive

newList =  [" Milan", " London", " London"]

Conclusion of niceTripleCombo(coolWords)

Ultimately, we end up with Milan, London, London

Now in the function iterator(),

Due to having 2 instances of London, the if condition will fail, triggering the else block.

First issue arises here, you forgot to initialize the newList as empty. Consequently, upon running niceTripleCombo again, it will append three more cities.

For instance, you might end up with

[" Milan", " London", " London", " Amsterdam", " Malaga", " Sofia"]

Secondly, the statement

return niceTripleCombo(coolWords);
will not yield any result.

The reason for the absence of a return value is that you are returning a function [niceTripleCombo(coolWords)] which itself lacks a return statement.

Your function should either return a value or if returning a function, that function must return a value. In your case, the function niceTripleCombo(coolWords) lacks a return statement and by default, a JavaScript function returns undefined if no other value is specified.

This explains why you are receiving undefined as output.

To rectify this, adjust the else block in your iterator like this:

else {
  newList = [];
  niceTripleCombo(coolWords);
  return iterator();
}

With this modification, you should no longer encounter undefined. Additionally, there is no necessity to pass niceTripleCombo to iterator since the former is not utilized within the latter.

For further information on return, refer to MDN: return statement

Answer №2

Imagine your newList Array contains the following values:

 [" Paris", " Paris", " Rome"]

or a similar scenario where one of the array elements is the same. In this case, when your iterator encounters a repeated element, the if condition fails and then you inadvertently execute

niceTripleCombo(coolWords)

However, this function does not have a return value, resulting in an undefined output.

Answer №3

Some pointers to consider regarding your code:

  • You are not iterating over anything, you are simply checking once.
  • If your goal is to obtain a unique trio of words, the current method may waste a lot of processing cycles if the randomizer does not generate the desired numbers.
  • If you are passing an array around, there is no need to make it a global variable. This approach renders your iterator redundant.
  • Your guessing function lacks a return value, resulting in it returning undefined.

Here's my suggestion:

var coolWords = ["Amsterdam", "Berlin", "Sofia", "Prague", "Lisbon", "London", "Malaga", "Copenhagen", "Milan"];

function niceTripleCombo( list ) {

  // Create a copy of the list to avoid modifying the original.
  let words = list.slice();
  let result = [];
  
  for( let i = 0; i < 3; i++ ){
    
    // Utilize splice to extract a word from the copied array
    // This also removes the word from the array,
    // preventing it from being selected again.
    result.push(
      words.splice( Math.floor( Math.random() * words.length ), 1 )[ 0 ]
    );
    
  }
  
  return result;
  
};

console.log( niceTripleCombo(coolWords) );

This approach ensures the return of a list containing three unique words. It achieves this by selecting a random word from the array, removing it, and adding it to the result. This process repeats with a shortened array, minimizing the needed cycles to only three iterations, regardless of the randomizer's behavior.

Answer №4

newList array must be returned within the niceTripleCombo function.

var citiesList = ["Tokyo", "Sydney", "Dubai", "Paris", "Rome", "Moscow", "New York", "Rio de Janeiro", "Los Angeles"];

var newList = [];

function niceTripleCombo(citiesList) {
  newList.length = 0; // Clear the array before starting
  for (let i = 0; i < 3; i++) {
    var combination = citiesList[Math.floor(Math.random()*citiesList.length)];
    newList.push(" " + combination);
  };
  return newList; //Returning an array.
};

function checkDuplicates(x) {
  if (newList[0] !== newList[1] && newList[1] !== newList[2] && newList[1] !== newList[3]) {
    return newList;
  } else {
    return niceTripleCombo(citiesList);
  }
};

console.log(checkDuplicates(niceTripleCombo(citiesList)));

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

What is the best way to manage errors and responses before passing them on to the subscriber when using rxjs lastValueFrom with the pipe operator and take(1

I'm seeking advice on the following code snippet: async getItemById(idParam: string): Promise<any> { return await lastValueFrom<any>(this.http.get('http://localhost:3000/api/item?id=' + idParam).pipe(take(1))) } What is the ...

Ensuring proper input with JavaScript form validation

Currently, I am working on implementing a basic form validation feature, but it is not functioning as intended. The desired behavior is for the field border to change color to green or red based on its validity, while displaying text indicating whether t ...

The function client.guilds.find cannot be located

Hey there! I've been tasked with working on a Discord bot that requires several dependencies to function properly. I've installed the necessary dependencies and attempted to run the bot using 'forever -o out.log bot.js'. However, I enc ...

Updating the jQuery AJAX URL dynamically based on user input in a form submission

Exploring the world of AJAX and form submission, I find myself in need of assistance. My webpage is designed to display real-time stock market data, updating fields with the latest price, change, high, low, and more. I am currently attempting to modify th ...

Looking to optimize Laravel performance by eager loading both belongsTo and HasMany relationships?

I have a pair of interconnected models called Product and ProductCategory. Each product belongs to one product category, while each product category can house multiple products. Let's take a look at the models: Product: <?php namespace App\ ...

Leveraging configuration files in AngularJS

I'm working on an Angular application that communicates with a Node.js backend Express application. I am using a config file to store environment variables for my Node app. Here's how I access the config file in my Node app: index.js var port = ...

Problem with Ext.net TabPanel

I am encountering a problem with the Ext.net TabPanel. Every time the page containing the tab panel is opened for the first time after the application has been rebuilt, it throws an error Uncaught TypeError: Object [object Object] has no method 'getCo ...

Utilizing Ajax, Jquery, and Struts2 for File Uploading

Can someone please provide guidance on uploading files using a combination of Ajax, jQuery, and Struts2? I have searched through numerous tutorials online but haven't found a suitable solution yet. The goal is to trigger a JavaScript function when a b ...

Rails 4 - Functional JS errors are absent yet JavaScript functionality is not operational

Currently, I am delving into the world of Ruby on Rails and making an effort to grasp the concept of the asset pipeline. As a means to learn more effectively, I decided to construct my website using Rails and learn along the way. However, after integrating ...

What is the best way to collapse additional submenus and perform a search within a menu?

Whenever a sub-menu is activated, only the current sub-menu should be open while the others remain closed. I need the search function to be enabled on the text box and display all items containing the specified value while also changing the color of <a ...

Can one integrate various angular components constructed using distinct versions of Angular?

Is it feasible to utilize various angular components (custom elements) created with different versions of Angular? I've heard concerns about zone.js causing global scope pollution. Appreciate your response! ...

"Incorporating splice in a for loop is causing issues and not functioning

I've been attempting to remove an item from an array, but for some reason, it's not working. Here's the code I'm using: vm.Continue = function () { $scope.invalidList = []; if (vm.errorexsist === true) { var table = doc ...

I must update the menu to show only one sub-menu at a time, ensuring that multiple menus cannot be displayed simultaneously

When I click on a menu option, it displays correctly, but when I click on another option, both are displayed. The goal is to only display one at a time. https://i.sstatic.net/J6vLf.png $('.sub-menu ul').hide(); $(".sub-menu a").click( ...

Difficulty encountered while implementing the if-else statement in raycasting operations

Currently, I am experimenting with raycasting to determine if my mouse is pointing at an object. The function seems to be working fine when the object is not being touched - it correctly prints out "didnt touch". However, when the object is touched, it s ...

Embed a Vaadin component within an element dynamically generated by a Javascript component

I am currently designing a Vaadin application and working on a custom Javascript component, which is a subclass of AbstractJavascriptComponent. This component uses jQuery to generate a table-like structure. In certain scenarios, users should be able to in ...

Dynamic updating of scores using Ajax from user input

My goal is to design a form that includes three "Likert Scale" input fields. Each of these three inputs will have a total of 10 points that can be distributed among them. The submit button should become enabled when the score reaches 0, allowing users to s ...

Perform Addition of Two Input Values Automatically without the need for any manual clicking of buttons

Despite trying all available codes, I have been unable to make it work. Here is the code: <!doctype html> <html lang="en"> <head> <!-- Required meta tags --> <meta charset="utf-8"> <meta na ...

Transform JavaScript code into HTML using jQuery.`

I have a piece of HTML and JavaScript code. The JavaScript code is currently in jQuery, but I want to convert it to vanilla JavaScript: // Vanilla JavaScript code document.querySelectorAll('.hello[type="checkbox"]').forEach(item => { item ...

When altering the color of a mesh in Three.js, only a single face is impacted by the modification

I have a GLB model with multiple parts and hierarchy. My goal is to highlight a specific part of the assembly on mouseover. The code snippet I am using for this functionality is as follows: raycaster.setFromCamera( pointer, camera ); ...

Converting the 'require' call to an import may be a more efficient method when importing package.json in a typescript file

In my current project, I am creating a class where I am directly accessing the package version number like this: const pkg = require('../package.json') export class MyClass() { constructor() { // Set the base version from package.jso ...