Untitled

 avatar
unknown
plain_text
2 years ago
3.8 kB
10
Indexable

class MyArray {
  constructor(initialSize = 1) {
    if (
      Number(initialSize) !== initialSize ||
      Math.round(initialSize) !== initialSize
    ) {
      throw new Error('Длина массива должна быть целым числом');
    }

    if (!(initialSize > 0)) {
      throw new Error('Размер массива должен быть больше нуля');
    }

    this.size = initialSize;
    this.memory = allocate(initialSize);
    this.length = 0;
  }

  // Возвращает значение по индексу.
  // Если индекс за пределами — кидает ошибку.
  get(index) {
    if (index in this.memory) {
      return this.memory[index];
    } else {
      throw new Error('индекс за пределами');
    }
  }

  // Устанавливает значение по индексу.
  // Если индекс за пределами — кидает ошибку.
  set(index, value) {
    if (index in this.memory) {
      this.memory[index] = value;
    } else {
      throw new Error('индекс за пределами');
    }
  }

  // Добавляет новый элемент в массив.
  // Если index не определён — добавляет в конец массива.
  // В противном случае — добавляет по индексу со сдвигом
  // всех последующих элементов.
  // Если индекс за пределами - кидает ошибку.
  // Увеличивает выделенную память вдвое, если необходимо.
  // Возвращает новую длину массива.
  add(value, index) {
    if (index >= this.length) {
      throw new Error('индекс за пределами 1');
    }
    if (index === undefined) {
      this.memory[this.length] = value;
      this.length += 1;
    }
    if (index in this.memory) {
      const obj1 = {};
      const obj2 = {};
      for (let key in this.memory) {
        if (+key === index) {
          obj2[key] = value;
        } else if (+key > index) {
          obj2[key] = this.memory[+key - 1];
        } else {
          obj1[key] = this.memory[key];
        }
      }
      obj2[this.length] = this.memory[this.length - 1];
      this.memory = { ...obj1, ...obj2 };
      this.length += 1;
    }
    if (this.size === this.length) {
      this.size *= 2;
    }
  }

  // Удаляет элемент по индексу со сдвигом всех последующих элементов.
  // Если индекс за пределами - кидает ошибку.
  // Возвращает новую длину массива.
  delete(index) {
    if (index >= this.length || index < 0 || this.memory[index] === undefined) {
      throw new Error('индекс за пределами 2');
    }
    if (index === 0 && this.memory[index] !== undefined && this.length === 1) {
      this.memory[index] = undefined;
      this.length = 0;
      this.size = 1;
    }
    if (this.length > 0) {
      const obj1 = {};
      const obj2 = {};
      for (let key in this.memory) {
        if (+key === index) {
          continue;
        } else if (+key > index) {
          obj2[key - 1] = this.memory[key];
        } else {
          obj1[key] = this.memory[key];
        }
      }
      this.memory = { ...obj1, ...obj2 };
      this.length -= 1;
    }
  }
}

function allocate(size) {
  const memory = {};

  for (let i = 0; i < size; i++) {
    memory[i] = undefined;
  }

  return memory;
}

const myArray = new MyArray();
myArray.add(10);
myArray.add(20);
myArray.add(30);
myArray.add(40);
myArray.delete(3);
myArray.delete(2);
myArray.delete(0);

console.log({
  size: myArray.size,
  memory: myArray.memory,
  length: myArray.length,
});
Editor is loading...