JavaScript generator function

I'm working on creating a function generator that can iterate over an infinite sequence, similar to the fibonacci sequence. The goal is to have it return the next value in the sequence each time it's called. Here is the function prototype I've been given:

function genfib() {
  return function fib() {
  }
}

This is how it should be used:

var fib = genfib();
fib(); // -> returns 0
fib(); // -> returns 1
fib(); // -> returns 1
fib(); // -> returns 2

I'm struggling to understand what exactly happens each time I call fib(). I attempted to change the function like this:

function genfib() {
  var count = 1;
  if (count === 1) {
    count++;
    yield 0;
  }
  else if (count === 2) {
    count++;
    yield 1;
  }
  var a = 0;
  var b = 1;
  return function fib() {
    while(1) {
      count = a + b;
      a = b;
      b = count;
      yield count;
    }
  }
}

Unfortunately, this approach isn't working as expected. I'm unsure of how to structure it so that it follows the initial conditions for the first two numbers in the Fibonacci sequence and then enters the while loop for subsequent calls.

Answer №1

To incorporate ES6 generators and utilize the yield keyword, follow this method:

function *fibonacci() {
    var [prev, current] = [0, 1];

    while (true) {
        [prev, current] = [current, current+prev];
        yield current;
    }
}

An option to iterate through the results is by using a for-of loop:

for (var v of fibonacci()) {
    console.log(v);
    if (v > 100) break;
}

It's important to note that the destructuring assignment var [prev, current] = is supported in FF and Traceur but not Chrome or node currently. If needed, it can be rewritten as:

function *fibonacci() {
    var prev = 0, current = 1, oldprev;

    while (true) {
        oldprev = prev;
        prev = current;
        yield current += oldprev;
    }
}

If you prefer the function prototype semantics provided earlier, then:

function genfib() {
    var iterator = fibonacci();
    return function fib() {
        return iterator.next().value;
    };
}

Answer №2

In my opinion, the use of `yield` in this particular function seems unnecessary. It's just a clever utilization of JavaScript closure.

Your initial approach was on the right track - indeed, you do require a function that returns another function. The key lies in maintaining two variables outside the inner function: one for the old value and one for the next value. Inside the function, calculating the new `next` value is straightforward; then simply update `old` to hold the previous `next` value. Swapping their values can be accomplished with a placeholder variable.

function genfib() {
  var next = 1
  var old = 0
  return function fib() {
    var newNext= next + old
    old = next
    next = newNext
    return next
  }
}

var fib = genfib()

var result = []

for ( var i = 0; i < 10; i++ )
  result.push( fib() )

document.body.innerHTML = result.join()

Nevertheless, it's worth noting that the first function call presents a unique scenario (where 1 should be returned twice). I'll leave it up to you to address this special case :-)

Answer №3

function* fibonacci(num) {
  var x = num, y = x + 1, z = x;

  while (true) {
    yield x;
    z = x;
    x = y;
    y = z + y;
  }
}

var sequence = fibonacci(0);
console.log(sequence.next().value); // 0
console.log(sequence.next().value); // 1
console.log(sequence.next().value); // 1
console.log(sequence.next().value); // 2
console.log(sequence.next().value); // 3
console.log(sequence.next().value); // 5
console.log(sequence.next().value); // 8
console.log(sequence.next().value); // 13

To learn more about using generators in JavaScript, check out this informative post.

Answer №4

function* fibonacci(){
  var fn1 = 1;
  var fn2 = 1;
  while (true){  
    var current = fn2;
    fn2 = fn1;
    fn1 = fn1 + current;
    var reset = yield current;
    if (reset){
        fn1 = 1;
        fn2 = 1;
    }
  }
}

var sequence = fibonacci();
console.log(sequence.next().value);     // 1
console.log(sequence.next().value);     // 1
console.log(sequence.next().value);     // 2
console.log(sequence.next().value);     // 3
console.log(sequence.next().value);     // 5
console.log(sequence.next().value);     // 8
console.log(sequence.next().value);     // 13
console.log(sequence.next(true).value); // 1
console.log(sequence.next().value);     // 1
console.log(sequence.next().value);     // 2
console.log(sequence.next().value);     // 3

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

Error encountered: DataTable - Unable to retrieve the 'length' property of a null value

I am currently using a datatable in my project: function drawRadnici() { $('#tableradnici').dataTable({ "ajax": { "url": 'track_radnici.php', "type": 'POST' ...

What is the functionality of the "respond_with_navigational" feature?

Currently, I am integrating Devise and DeviseInvitable to handle authentication in my application. However, I'm facing challenges when trying to incorporate AJAX functionality into InvitationsController#update. The structure of the controller in Devis ...

Synchronization-free API and callback functions

I am in need of utilizing an asynchronous service. My current approach involves sending data to this service using PHP and CURL, as well as receiving data from a URL provided by the service. How can I effectively respond or wait for feedback from this serv ...

Analyzing a server's log data at regular intervals

Currently, I am working on a project where I need to parse a server log file using JavaScript every 24 hours and then store the extracted information in a MongoDB database. The process of parsing the data and storing it is what I find to be the most chall ...

a script in JavaScript that retrieves the selected value from a radio button box

I have an AJAX table where I need to highlight one of the rows with a radio box on the left side. However, I lack proficiency in JavaScript and would like assistance in retrieving the value of the radio box by its ID from this table once it has been select ...

Issue with ngModelChange and change events not functioning properly in Internet Explorer 11

Within a text input field, I have implemented single-way binding in addition to utilizing a number formatter pipe. I have also set up an (ngModelChange) event handler to remove any commas that are added by the number formatter, and a (change) event to tri ...

Issue with router failing to load default route upon application startup

I've been grappling with this issue for the past day and a half and have not made any progress. My goal is to load my angular app and have it default to a specific page when bootstrapped, but it keeps redirecting to a different route. The intended de ...

Adding a distinct key and its corresponding value to an array in Vue for a unique

I am attempting to add key-value pairs into an array while ensuring their uniqueness. Currently, I am trying the following approach: for (const [key, value] of Object.entries(check)) { console.log(`${key}: ${value}`); this.inputFields. ...

Reactjs: Could someone provide a more detailed explanation of this statement?

After reading this line in the documentation here, I came across an interesting code snippet. this.setState({ chats: [...this.state.chats, data], test: '' }); It seems like we are adding to the 'chats' array in the state, but I&ap ...

Tips for iterating through JSON data and combining rows with matching state IDs

I have a JSON file containing data about US senators, with two senators listed for each state. My goal is to iterate over this JSON file and create a new JavaScript object where the state ID serves as the key, with two properties assigned to each key: name ...

I encountered an issue where I am unable to subtract from jQuery's .outerHeight() within an if statement

I've been working on creating an ajax request that triggers when a div is scrolled to the bottom. I thought I had it figured out with this code, but I've run into an issue. Everything works fine without subtracting 100 from the elem.outerHeight() ...

Techniques for adding values to arrays in JavaScript

My Anticipated Result let Album = { album_desc: AlbumTitle, id: 1, album_title: 'ss', AlbumDescription: 'sdsd', ImageName: 'image.jpg', album_pics: below array }; I am looking to dynamically p ...

Executing functions with iterations

Can anyone help me understand why my buttons always output 100 in the console log when clicked? Any ideas on how to resolve this issue? function SampleFunction(param){ console.log(param); } for (i = 0; i < 100; i++) { $("#btn-" + i).on('c ...

Different ways to organize and implement javascript libraries without relying on npm

We have been collaborating on various projects within a unified lerna repository structure, including: lerna |----- app1 - application 1 |----- app2 - application 2 |----- appN - application N |----- commondb (shared database libraries for app1, ap ...

JavaScript's method .focusout() is used to trigger when

Looking to create a custom select box. Is there a way to hide the <ul> when the mouse is clicked outside of the list element? Ideally, this should be accomplished without using jQuery and considering that "onblur" does not capture mouse clicks that ...

Array Filtering Results in an Empty Array of Objects

I'm currently attempting to filter out all objects from the projects array that do not appear in the savedProjects array, but I'm ending up with an empty result. Could it be that I am approaching the filtering process incorrectly? Here's my ...

Buttons for toggling D3 bubble chart display mode

As a beginner in D3.js, I am exploring the creation of a bubble chart with a toggle button to switch between different presidential campaign candidates. While I succeeded in making the chart for one candidate, I am encountering difficulties implementing th ...

What is causing elements like divs, paragraphs, or text not to display within an ion-item after an ion-input is added?

I am currently working on validating a simple form and everything seems to be functioning properly. However, I have encountered an issue with displaying text messages within an ionic 3 list item. The ion-item consists of an ion-input element. When I place ...

Tips for displaying an entire division without altering the position of its content

I am looking to create a pop-up effect for the entire div that includes images, text, and more. However, I have encountered an issue where when I activate the pop-up feature, the position of the content within the div changes. My goal is to have the div zo ...

Access the style of the first script tag using document.getElementsByTagName('script')[0].style or simply refer to the style of the document body with document.body.style

Many individuals opt for: document.getElementsByTagName('script')[0].style While others prefer: document.body.style. Are there any notable differences between the two methods? EDIT: Here's an example using the first option: ...