The topic at hand pertains to a specific exercise featured in the well-known book Eloquent JavaScript

In this exercise, the final step is to create a recursive function that takes a joined list and an index as parameters. The function's purpose is to find the value in the object within the list at the specified index. The code I have written seems to be functioning correctly as I can track its progress through console logs. However, I am encountering an issue with it returning 'undefined' as the value on the last occasion. I am puzzled by this and unable to determine the cause. The code seems to work fine for the index of 0. Here is the code snippet:

Initially, the list looks like this:

list = {
    value: 1,
    rest: {
        value: 2,
        rest: {
            value: 3,
            rest: null
            }
        }
    };



   const nth = (list, targetNum) => {
   let value = Object.values(list)[0];
   if (targetNum == 0) {
       return value;
   } else {
       targetNum = targetNum -1;
       list = Object.values(list)[1];
    //    console.log(value);
    //    console.log(targetNum);
    //    console.log(list);
       nth(list, targetNum);
   }
};
console.log(nth(arrayToList([1,2,3]),2)); 

Below is the code for arrayToList, which was the initial part of the exercise. Feel free to provide any feedback, as the hints suggested building the list from the end:

const arrayToList = (arr) => { 
    let list = {
        value: arr[0],
        rest: nestObject()
    };
    function nestObject() {
        let rest = {};
        arr.shift();
        const length = arr.length;
        if (length == 1) {
            rest.value = arr[0];
            rest.rest = null;
        } else {
            rest.value = arr[0];
            rest.rest = nestObject();
        }
        return rest;   
    }
    return list;
};

Answer №1

Both solutions provided are unnecessarily complex and verbose. In reality, both functions could be simplified into one-liners. Here are some tips:

When dealing with the toList function, you can follow these steps:

  • If the input array is empty, return null (base case)

  • To break down the input array, split it into the "head" (the first element) and the "tail" (the rest of the elements). For instance, [1,2,3,4] => 1 and [2,3,4]

  • Construct an object with value as the "head" and rest as toList applied to the "tail" (utilize recursion)

For a more advanced approach, you can perform the split directly in the function signature using destructuring:

const toList = ([head=null, ...tail]) => ...

A similar approach can be taken for the nth(list, N) function:

  • If N is zero, return list.value (base case)

  • Otherwise, recursively call nth with arguments list.rest and N-1

Once again, destructuring can enhance the function signature:

const nth = ({value, rest}, n) => 

If you're interested, here is the complete code:

const toList = ([value = null, ...rest]) =>
    value === null
        ? null
        : {value, rest: toList(rest)}

const nth = ({value, rest}, n) =>
    n === 0
        ? value
        : nth(rest, n - 1)

//

let lst = toList(['a', 'b', 'c', 'd', 'e', 'f'])
// or simply toList('abcdef')

console.log(lst)

console.log(nth(lst, 0))
console.log(nth(lst, 4))

Answer №2

It is crucial to include a return statement when recursively calling the function nth. Without it, the logic will be executed but no value will be returned (unless the targetNum is 0).

const nth = (list, targetNum) => {
   let value = Object.values(list)[0];
   if (targetNum == 0) {
       return value;
   } else {
       targetNum = targetNum -1;
       list = Object.values(list)[1];
       return nth(list, targetNum); // Another return statement is required here
   }
};

Alternatively, the function can be expressed more concisely as:

const nth = (list, n) => n === 0 ? list.value : nth(list.rest, n - 1)

For those looking for a non-recursive implementation of arrayToList that constructs the list from the end:

const arrayToList = arr => arr.slice().reverse().reduce((rest, value) => ({value, rest}), null);

(Using slice in this context is to ensure the original array is not altered during the process.)

Answer №3

Georg has some truly elegant recursive solutions that I find quite appealing!

Additionally, I wanted to share a clever solution from a certain book that suggests "building the list from the end":

const arrayToList => (arr) => {
  var list
  while (arr.length) {
    list = {value: arr.pop(), rest: list}
  }
  return list
}

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

Implementing a pull-to-refresh feature in React Native using Redux

I need to implement pull to refresh functionality, but I'm unsure of what to call from _Refresh(). My actions, constants, and reducers are stored on another page. How can I trigger the API again? Thank you in advance for your assistance. class Homewo ...

When the page is dynamically loaded, Ng-repeat does not function as expected

I am working on a page that includes the following code snippet: <script> angular.module('myapp', []).controller('categoryCtrl', function($scope) { $scope.category = <? echo json_encode($myarr); ?>; $scope.subcatego ...

Expanding the size of a textarea using JavaScript

JavaScript: function adjustRows() { var value = document.getElementById("test1").value.length; if (value <= 18) { value.rows = 1; } else if (value > 18 && value < 36) { value.rows = 2; } else if (value > 36 && v ...

Harness the power of ng-click in conjunction with data-ng-href for a

I am attempting to create a button that takes the user to the product details while also having the ability to increase a counter using an ng-click function. <div class="row center-block save-button" > <a data-ng-href="/savings/{{saving._id}} ...

Is it feasible to utilize the .fadeTo() function in jQuery multiple times?

I need some help with writing a script that will display a warning message in a div tag every time a specific button is pressed. I chose to use the fadeTo method because my div tag is within a table and I want to avoid it collapsing. However, I'm noti ...

How can DataTables (JQuery) filter multiple columns using a text box with data stored in an array?

I've been attempting to create a multi-column filter similar to what's shown on this page () using an array containing all the data (referred to as 'my_array_data'). However, I'm facing issues with displaying those filter text boxe ...

Have Babel transpile configuration files into CommonJS format

I'm having trouble getting my Nuxt app to work with Jest for testing. I have a setupFilesAfterEnv property set with a setupTests.ts file that imports a translation file. The translations file uses ES6 import/export module syntax, but it seems like my ...

javascript get the value of the text field

Is there a way to calculate even and odd numbers using a text field for entering the range of values and a select tag to choose between even and odd? How can I retrieve the value from the text field in order to pass it to the calculation function? Custom ...

Detaching the jQuery event where the context is tied to the handler

My current challenge involves removing a jQuery event with a callback function bound using this. The issue arises from the fact that .bind() generates a new function each time it is called, causing difficulties when trying to remove the event. I am strugg ...

Include specific javascript files only for smartphones

Recently, I encountered an issue with a JavaScript code that swaps background images on scroll down. To address the problem with debounce, I ended up setting different debounce times for various browsers (I am aware this is not the ideal solution, but it&a ...

Is caching a feature in AngularJS, and are there methods available for disabling it?

var modalInstance = $modal.open({ templateUrl: '/template/edit-modal.html', controller: ModalInstanceCtrl2, resolve: { locations: function () { return locationToEdit; } }, scope: $scope.$new() }); ...

Enhance the JQuery dropdown by padding with zeros at the beginning for smooth incrementing

I have been attempting to customize a date dropdown in Sharepoint because the default minutes dropdown only allows selection in 5-minute intervals. Initially, I was able to make it work with the code below: $("select[id$='DateTimeFieldDateMinutes&apo ...

Why is the click event not working in IE8 for JavaScript / jQuery?

There seems to be an issue with the program not functioning properly in IE8 for some users. The website in question is an English course where certain individuals are experiencing difficulty clicking on the correct answers. To view a demonstration of this ...

What are the steps for leveraging a proxy with NodeJS and Selenium?

While researching the topic on proxies in the documentation, I came across a method to set up a proxy while building a driver like this: var driver = new webdriver.Builder() .withCapabilities(webdriver.Capabilities.chrome()) .setProxy(proxy.manual ...

Handling the display of divs using two select elements

I've been pondering this problem for a while now, and I'm starting to believe that there may not be a solution. Essentially, what I am trying to achieve is the ability to select options from two dropdown menus which will then show or hide specifi ...

Accessing Headers in node request library

I need help retrieving the server response header for a request from a server. import 'request' from 'request' var url = "SOME_URL" var options = { url: url }; var callback = function(error, response, body) { if(!error){ ...

Ways to organize backbone models, views, and collections using vim?

I am a fan of vim's folding feature, but I have encountered some challenges when trying to fold backbone models, views, and collections. This is because backbone does not follow the traditional prototype syntax, but instead uses a .extend() based synt ...

A guide on clearing the selected value in a dropdown menu with Angular.js

Can someone assist me with setting the drop-down value to blank after completing an action in Angular.js? Below is my code explanation: <div style="height:270px; overflow-x:hidden; overflow-y:scroll;" ng-show="viewOrderTable"> <div class="table-r ...

Can you explain the execution process of this Http.post method and provide details about the code path it follows

As I delve into the world of web development, one aspect that has me stumped is the functionality of the Http.post section within a project I stumbled upon on GitHub. Specifically, this pertains to an ExpressJS with Typescript repository I came across. So, ...

Guide to creating a dictionary array on-the-fly:

I have been working on updating years to make it more dynamic by using the starting year (2010) and ending year (2018). Originally, I used a for loop to address this, but I am curious if there is a more efficient way to refactor years. Current arrangemen ...