2016-08-17 1 views
0

Я использую объект ES6 Map, где ключи являются символом, числом или строкой. Я выбираю карту по массиву, потому что я много ищу элементы по ключу и не хочу перебирать массив каждый раз, когда мне нужно найти ключ. Это также подходит мне ключом, шаблон ценности.
Там также будет много операций, где мне нужен следующий и предыдущий элемент, иногда первый и последний.
В основном это представляет таблицу для сетки.
В настоящее время я использую:ES6 Карта или массив: нужно сначала, последнее, previuos, next, get (mix array и Map) в TypeScript

  • следующие: Перебрать Map.keys(), пока не нашли тока и вернуться на следующем
  • предыдущие: Перебрать Map.keys() помнит последний ключ, и когда нашел текущее возвращение последнего нажатия
  • первое: Map.keys().next().value
  • последняя: Array.from(this._data.keys()).reverse()[0];

Другая идея для последнего:

let lastKey: any; //I am using TypeScript with "noImplicitAny": true 
for (lastKey of map.keys()) { } 

Какой из них лучше?

Есть ли другие возможные решения? Я также думал о создании нового объекта, который имел бы массив и карту, но это, похоже, много или, может быть, нет? Что-то вроде этого:

class MapArray 
{ 
    map = new Map<string | number | symbol, number>(); //map between keys and array indexes 
    array: Array<any> = []; 

    constructor(data: Array<any>) 
    { 
     for (const d in data) 
     { 
      this.add(d); 
     } 
    } 

    add(value: any) 
    { 
     this.array.push(value); 
     this.map.set(Symbol(), this.array.length - 1); 
    } 

    next(currentKey: symbol) 
    { 
     const current = this.map.get(currentKey); 

     if (typeof current !== "undefined") 
     { 
      if (current >= this.array.length - 1) 
       return null; //current is last item 
      return this.array[current + 1]; 
     } 
     return this.array[0]; //return first 
    } 

    previous(currentKey: symbol) 
    { 
     const current = this.map.get(currentKey); 

     if (typeof current !== "undefined") 
     { 
      if (current == 0) 
       return null; //current is first item 
      return this.array[current - 1]; 
     } 
     return this.array[this.array.length - 1];  //return last 
    } 

    get(key: symbol) 
    { 
     const index = this.map.get(key); 
     if (typeof index !== "undefined") 
      return this.array[index]; 
     return null; 
    } 

    set(key: symbol, value: any) 
    { 
     const index = this.map.get(key); 
     if (typeof index !== "undefined") 
      this.array[index] = value; 
     else 
      this.add(value); 
    } 
    //TODO write delete 
    //TODO write first/last 
    //TODO write generator 
} 

Как вы думаете? Данные обычно представляют собой малый массив (20 объектов объектов с 3 свойствами) или более крупный массив с большими данными (1000 объектов объектов со 100 или более свойствами).
Код будет в основном работать на мобильных телефонах, поэтому важно использовать память и производительность.

+0

На самом деле не имеет значения, сколько свойств имеют объекты в структуре. – Bergi

+0

"* Другая идея для последнего *" ... намного лучше. Ему не нужно создавать экземпляр массива или перемещать вещи ('reverse'). Конечно, он все еще ужасно неэффективен, но не по меньшей мере по памяти. – Bergi

+0

Вам действительно нужно «удалить»? И: это происходит много? – Bergi

ответ

2

Я также думал о создании нового класса, который имел бы массив и карту, но это похоже на многое?

Нет, это правильный курс действий. Это единственный выбор для получения разумной производительности для индексированного доступа.

Абстракция со всеми операциями, которые вы используете, всегда будет полезна. Вы можете поменять реализацию на что-то более простое (когда этого достаточно) или более сложное (когда оно вам нужно) без изменения кода, который использует структуру.

Смежные вопросы