array-set.js (2394B)
1 /* -*- Mode: js; js-indent-level: 2; -*- */ 2 /* 3 * Copyright 2011 Mozilla Foundation and contributors 4 * Licensed under the New BSD license. See LICENSE or: 5 * http://opensource.org/licenses/BSD-3-Clause 6 */ 7 8 /** 9 * A data structure which is a combination of an array and a set. Adding a new 10 * member is O(1), testing for membership is O(1), and finding the index of an 11 * element is O(1). Removing elements from the set is not supported. Only 12 * strings are supported for membership. 13 */ 14 class ArraySet { 15 constructor() { 16 this._array = []; 17 this._set = new Map(); 18 } 19 20 /** 21 * Static method for creating ArraySet instances from an existing array. 22 */ 23 static fromArray(aArray, aAllowDuplicates) { 24 const set = new ArraySet(); 25 for (let i = 0, len = aArray.length; i < len; i++) { 26 set.add(aArray[i], aAllowDuplicates); 27 } 28 return set; 29 } 30 31 /** 32 * Return how many unique items are in this ArraySet. If duplicates have been 33 * added, than those do not count towards the size. 34 * 35 * @returns Number 36 */ 37 size() { 38 return this._set.size; 39 } 40 41 /** 42 * Add the given string to this set. 43 * 44 * @param String aStr 45 */ 46 add(aStr, aAllowDuplicates) { 47 const isDuplicate = this.has(aStr); 48 const idx = this._array.length; 49 if (!isDuplicate || aAllowDuplicates) { 50 this._array.push(aStr); 51 } 52 if (!isDuplicate) { 53 this._set.set(aStr, idx); 54 } 55 } 56 57 /** 58 * Is the given string a member of this set? 59 * 60 * @param String aStr 61 */ 62 has(aStr) { 63 return this._set.has(aStr); 64 } 65 66 /** 67 * What is the index of the given string in the array? 68 * 69 * @param String aStr 70 */ 71 indexOf(aStr) { 72 const idx = this._set.get(aStr); 73 if (idx >= 0) { 74 return idx; 75 } 76 throw new Error('"' + aStr + '" is not in the set.'); 77 } 78 79 /** 80 * What is the element at the given index? 81 * 82 * @param Number aIdx 83 */ 84 at(aIdx) { 85 if (aIdx >= 0 && aIdx < this._array.length) { 86 return this._array[aIdx]; 87 } 88 throw new Error("No element indexed by " + aIdx); 89 } 90 91 /** 92 * Returns the array representation of this set (which has the proper indices 93 * indicated by indexOf). Note that this is a copy of the internal array used 94 * for storing the members so that no one can mess with internal state. 95 */ 96 toArray() { 97 return this._array.slice(); 98 } 99 } 100 exports.ArraySet = ArraySet;