Search code examples
javascriptlistimplementation

implement a list with a static method javascript


I must reimplement a list and the method forEach with the following instructions:

// Do not construct any array literal ([]) in your solution.

// Do not construct any arrays through new Array in your solution.

// DO not use any of the Array.prototype methods in your solution.

// You may use the destructuring and spreading (...) syntax from Iterable.

the result should look like:

const list = List.create(1, 2)
list.forEach((item) => console.log(item))

Here is my incomplete solution:

export class List {

  constuctor(){
    
  }

  public static create(...values: number[]): List {
    // Do *not* construct any array literal ([]) in your solution.
    // Do *not* construct any arrays through new Array in your solution.
    // DO *not* use any of the Array.prototype methods in your solution.

        // You may use the destructuring and spreading (...) syntax from Iterable.
        List list = new List();
        values.forEach(function(item){
          list.push(item);
        });  
        return list;
      }
    
      public forEach(callback: any){
        for (let i = 0; i<this.length ; i++){
           callback(this[i], i, this);
        }
      }
    
    }

in the create loop, but the problem, as a static method, the this is not recognized

EDITED thanks to comments


Solution

  • ...this is not recognised

    It is. But you have not given this any property. And this is because:

    • constuctor should be written as constructor
    • You need to define a push method (since you call it in create)
    • You need to define a length property (since you reference it in forEach)

    Furthermore, there some other issues:

    • you write that Array.prototype functions cannot be used, but your code has values.forEach(), ... so that is a violation of that rule. Use a for..of loop instead.

    Here is your code with those remarks taken on board:

    class List {
      constructor() {
        this.length = 0;    
      }
    
      push(value) {
        this[this.length++] = value;
      }
    
      static create(...values) {
        let list = new List();
        for (let item of values) {
          list.push(item);
        }
        return list;
      }
        
      forEach(callback) {
        for (let i = 0; i < this.length ; i++) {
          callback(this[i], i, this);
        }
      }
    }
    
    
    const list = List.create(1, 2)
    list.forEach((item) => console.log(item))

    Remarks

    The above "test" will be fine, but when also assignments to properties are to work correctly, like list[2] = 3, then there are more things to take care of. Take for instance this program:

    const list = List.create(1, 2);
    list[5] = 42; // should update length
    list.check = true; // should not update length
    console.log("length = " + list.length);
    console.log("enumerable keys are " + Object.keys(list));
    list.forEach((item) => console.log(item)); // should not output empty slots
    list.length = 1; // should delete some index properties
    list.forEach((item) => console.log(item)); // should not output deleted items
    

    ...then the output should be:

    length = 6
    enumerable keys are 0,1,5,check
    1
    2
    42
    1
    

    You can make this happen by trapping the access to properties, and making length a getter/setter. But you'd also need to distinguish between properties that are array indices, and which are not, so all-in-all that would make the code less trivial.