Есть ли такая структура данных, как набор Java в JavaScript?

Я хочу использовать структуру данных в JavaScript, которая может использоваться для хранения количества идентификаторов. Я должен проверить, существует ли ключ в этом наборе, например Java Sets.

Я хочу добиться одинакового поведения следующим образом (этот код находится на Java):

Set<String> st = new HashSet<String>();
//add elemets

if(st.contains("aks") ){
  //do something
}

Я хочу эквивалент JavaScript/ dojo вышеуказанного кода.

Ответы

Ответ 1

Я написал реализацию JavaScript HashSet, которая делает то, что вы хотите, и позволяет любому объекту быть членом набора: http://code.google.com/p/jshashtable

Однако, если вам просто нужно хранить строки, вы можете сделать что-то более просто, сохранив элементы набора как имена свойств обычного объекта. Например:

function StringSet() {
    var setObj = {}, val = {};

    this.add = function(str) {
        setObj[str] = val;
    };

    this.contains = function(str) {
        return setObj[str] === val;
    };

    this.remove = function(str) {
        delete setObj[str];
    };

    this.values = function() {
        var values = [];
        for (var i in setObj) {
            if (setObj[i] === val) {
                values.push(i);
            }
        }
        return values;
    };
}

Замечание о реализации: val - это объект, используемый внутри с помощью реализации StringSet, которая уникальна для каждого набора. Сравнивая значения свойств объекта, имена свойств которого составляют набор (setObj) по сравнению с val, устраняет необходимость проверки hasOwnProperty() и гарантирует, что только строки, которые были добавлены в набор, будут отображаться в values.

Пример использования:

var set = new StringSet();
set.add("foo");
set.add("bar");

alert(set.contains("foo")); // true
alert(set.contains("baz")); // false

set.values(); // ["foo", "bar"], though not necessarily in that order
set.remove("foo");
set.values(); // ["bar"]

Ответ 2

Почему бы не использовать обычный объект и проверить, существует ли ключ с JavaScript hasOwnProperty?

var x = {};
x['key'] = 'val';
x.hasOwnProperty('key'); // true //
x.hasOwnProperty('key2'); // false //

И вот более продвинутый прецедент:

var x = {};
var prefix = 'item_';
for(var i=0;i<10;i++){
   x[prefix+i] = 'value '+(i+1);
}
x.hasOwnProperty('item_6'); // true //
x.hasOwnProperty('other key'); // false //

Удаление элементов может быть выполнено следующим образом:

delete x['key'];

Ответ 3

Нет Dojo, это родное для Javascript. Используйте объекты. Похоже, вам нужны только ключи, а не значения. Поиск - постоянное время.

var st = {'aks':1, 'foo':1, 'bar':1};  // or could start with empty {}. 1 could be any value of any type, it just short.

//add elements
st.baz = 1;

//or load up dynamically

myArrayOfStrings.forEach(function(key){
 st[key] = 1;
});


if("aks" in st){
  //do something
}

Ответ 4

Возможно, с ассоциативным массивом /Hashtable/dictionary (я не знаю, как он называется именно), используя в качестве значений заданные элементы как ключи и "что-нибудь еще".

insert: mySet[key] = "Whatever";

delete: mySet[key] = null;

check: if (mySet[key] != null) { ... }

Ответ 5

Hash - хороший кандидат на реализацию Set. Вы можете создать набор, используя такую ​​функцию:

function set () {
    var result = {};
    for (var i = 0; i < arguments.length; i++) result[arguments[i]] = true;
    return result;
}

Например:

x = set([1,2,2,4])
x[1] #==> true
x[3] #==> false
x[5] = true; # add element to the set
x[5] = false; # remove element from the set

Ответ 6

У наборов нет ключей. Они имеют только набор значений, но карты имеют пары объектов key/value.

В результате у вас есть 2 варианта. У каждого из них есть свои недостатки и преимущества:

  • Вы можете использовать описанный выше объект JavaScript. На самом деле это карта/ассоциативный массив/хеш-таблица. Одно из его преимуществ - вы можете гарантировать такую ​​структуру, что ключи - это уникальные предметы. Его недостаток связан с проблемой - вам нужно сохранить дополнительную информацию, которая вам вообще не нужна. Значения карт. прав и других ценностей. Это не имеет значения. Зачем они нужны?

  • Чтобы устранить предыдущий недостаток, вы можете использовать JavaScript-массивы. Но вам придется писать некоторые обертки, поэтому поведение массивов будет выглядеть как поведение элементов. Также операции, которые будут выполняться с помощью uniqueId, будут медленнее, чем те же, что и для хэш-таблиц, потому что вам придется выполнять итерацию по всем элементам массива.

Итак, я думаю, вы должны предпочесть hashtables для массивов, примеры, которые вы можете найти в других сообщениях. Но, вероятно, вам стоит рассмотреть возможность изменения структуры данных. не сохраняйте uniqueId в качестве ключей с значениями unselerss, если это возможно. Пусть ваши уникальные идентификаторы указывают на некоторые реальные объекты, для которых используются эти уникальные идентификаторы.

PS: еще одна вещь. Массивы также являются объектами. В результате их можно использовать как hashtables/maps.