W Eloquent JavaScript, Rozdział 4, zestaw wartości jest tworzony przez utworzenie obiektu i przechowywanie wartości jako nazw właściwości, przypisując dowolne wartości (np. True) jako wartości właściwości. Aby sprawdzić, czy wartość jest już zawarta w zbiorze, in
używany jest operator:
var set = {};
if (!'Tom' in set) {
set.Tom = true;
}
Czy to idiomatyczny JavaScript? Czy nie użyłbyś tablicy jeszcze lepiej?
var set = [];
if (!'Tom' in set) {
set.push = 'Tom';
}
javascript
set
helpermethod
źródło
źródło
'Tom' in set
ma wyglądać prawda? Wygląda na to, że masz błędne założenia na temat czegoś , a ja próbuję się dowiedzieć, o czym .if(!('Tom' in set))
. Obecnie to znaczyfalse in set
od!'Tom' === false
.Odpowiedzi:
Zestawy są teraz dostępne w ES2015 (aka ES6, czyli ECMAScript 6). ES6 to obecny standard JavaScript od czerwca 2015.
Pierwsze dwa przykłady z książki Axela Rauschmayera Exploring ES6 :
> let set = new Set(); > set.add('red') > set.has('red') true > set.delete('red') true > set.has('red') false
> let set = new Set(); > set.add('red') > set.add('green') > set.size 2 > set.clear(); > set.size 0
Chciałbym sprawdzić Exploring ES6, jeśli chcesz dowiedzieć się więcej o zestawach w JavaScript. Książkę można czytać online bezpłatnie, ale jeśli chcesz wesprzeć autora, dr. Axela Rauschmayera, możesz ją kupić za około 30 dolarów.
Jeśli chcesz teraz używać Sets i ES6, możesz użyć Babel , transpilera ES6 do ES5 i jego polyfillów.
Edycja: Od 6 czerwca 2017 większość głównych przeglądarek ma pełną obsługę zestawu w swoich najnowszych wersjach (z wyjątkiem IE 11). Oznacza to, że możesz nie potrzebować babel, jeśli nie chcesz obsługiwać starszych przeglądarek. Jeśli chcesz zobaczyć kompatybilność w różnych przeglądarkach, w tym w bieżącej przeglądarce, sprawdź tabelę kompatybilności Kangax ES6 .
EDYTOWAĆ:
Tylko wyjaśnienie dotyczące inicjalizacji. Zestawy mogą przyjmować dowolną synchroniczną iterację w swoim konstruktorze. Oznacza to, że mogą przyjmować nie tylko tablice, ale także ciągi i iteratory. Weźmy na przykład następującą tablicę i inicjalizację ciągu zestawu:
const set1 = new Set(['a','a','b','b','c','c']); console.log(...set1); console.log(set1.size); const set2 = new Set("aabbcc"); console.log(...set2); console.log(set2.size);
Oba wyjścia tablicy i łańcucha są takie same. Zauważ, że
...set1
jest to składnia rozkładu . Wydaje się, że każdy element iterowalny jest dodawany jeden po drugim do zestawu, więc ponieważ zarówno tablica, jak i łańcuch mają te same elementy, a elementy są w tej samej kolejności, zestaw jest tworzony tak samo. Inną rzeczą, na którą należy zwrócić uwagę w przypadku zestawów, jest to, że podczas iteracji po nich kolejność iteracji jest zgodna z kolejnością wstawiania elementów do zestawu. Oto przykład iteracji na zestawie:const set1 = new Set(['a','a','b','b','c','c']); for(const element of set1) { console.log(element); }
Ponieważ możesz użyć dowolnej iteracji do zainicjowania zestawu, możesz nawet użyć iteratora z funkcji generatora . Oto dwa takie przykłady inicjalizacji iteratora, które dają ten sam wynik:
// a simple generator example function* getLetters1 () { yield 'a'; yield 'a'; yield 'b'; yield 'b'; yield 'c'; yield 'c'; } // a somewhat more commonplace generator example // with the same output as getLetters1. function* getLetters2 (letters, repeatTimes) { for(const letter of letters) { for(let i = 0; i < repeatTimes; ++i) { yield letter; } } } console.log("------ getLetters1 ------"); console.log(...getLetters1()); const set3 = new Set(getLetters1()); console.log(...set3); console.log(set3.size); console.log("------ getLetters2 ------"); console.log(...getLetters2('abc', 2)); const set4 = new Set(getLetters2('abc', 2)); console.log(...set4); console.log(set4.size);
Funkcje generatora podane w tych przykładach można po prostu napisać tak, aby się nie powtarzały, ale jeśli funkcja generatora jest bardziej skomplikowana i jeśli poniższe elementy nie wpływają zbyt negatywnie na wydajność, można użyć metody Set, aby pomóc uzyskać tylko wartości z generatora, który nie nie powtarzam.
Jeśli chcesz dowiedzieć się więcej o zestawach bez czytania rozdziału jego książki doktora Rauschmayera, zajrzyj do dokumentacji MDN na Set . MDN również więcej przykładów iteracji przez zestaw takich jak używanie
forEach
i stosowania.keys
,.values
i.entries
metod. MDN zawiera również przykłady, takie jak suma zestawów, przecięcie zestawów, różnica zestawów, symetryczna różnica między zbiorami i sprawdzanie nadzbiorów. Miejmy nadzieję, że większość tych operacji będzie dostępna w JavaScript bez konieczności budowania własnych funkcji, które je obsługują. W rzeczywistości istnieje ta propozycja TC39 dla nowych metod Set, która, miejmy nadzieję, powinna dodać następujące metody do Set in JavaScript w pewnym momencie w przyszłości, jeśli propozycja osiągnie etap 4:źródło
Używam obiektów dict jako zestawów. Działa to z ciągami i liczbami, ale przypuszczam, że spowodowałoby to problemy, gdybyś chciał mieć zestaw obiektów używających niestandardowych operatorów równości i porównania:
Tworzenie zestawu:
var example_set = { 'a':true, 'b':true, 'c':true }
Testowanie pod kątem włączenia do zestawu
if( example_set['a'] ){ alert('"a" is in set'); }
Dodanie elementu do zestawu
example_set['d'] = true;
Usunięcie elementu z zestawu
delete example_set['a']
;źródło
Set
. To pomogło.Zestawy nie pozwalają na zduplikowane wpisy i zazwyczaj nie gwarantują wstępnie zdefiniowanej kolejności. Tablice robią obie te rzeczy, naruszając w ten sposób to, co to znaczy być zbiorem (chyba że wykonasz dodatkowe sprawdzenia).
źródło
arr[id] = {"name": "Jake"};
Pierwszy sposób to idiomatyczny JavaScript.
Za każdym razem, gdy chcesz zapisać parę klucz / wartość, musisz użyć obiektu JavaScript. Jeśli chodzi o tablice, istnieje kilka problemów:
Indeks jest wartością liczbową.
Nie ma łatwego sposobu na sprawdzenie, czy wartość znajduje się w tablicy bez przechodzenia przez pętlę.
Zestaw nie pozwala na duplikaty. Tablica tak.
źródło
Jeśli chcesz utworzyć zestaw z tablicy, po prostu wykonaj:
let arr = [1, 1, 2, 1, 3]; let mySet = new Set(arr); // Set { 1, 2, 3 }
Jest to składnia cukru, która bardzo mi się spodobała podczas programowania w Pythonie, więc cieszę się, że ES6 w końcu umożliwiło zrobienie tego samego.
UWAGA: wtedy zdaję sobie sprawę, że to, co powiedziałem, nie odpowiadało bezpośrednio na twoje pytanie. Powodem tego "hackowania" w ES5 jest to, że czas wyszukiwania w obiekcie za pomocą kluczy jest znacznie szybszy (O (1)) niż w tablicy (O (n)). W aplikacjach o krytycznym znaczeniu dla wydajności można poświęcić tę odrobinę czytelności lub intuicji dla lepszej wydajności.
Ale hej, witaj w 2017 roku, w którym możesz teraz używać odpowiedniego zestawu we wszystkich głównych nowoczesnych przeglądarkach!
źródło
Zestawy w
ES6
/ES2015
:ES6
/ES2015
ma teraz wbudowane zestawy. Zestaw to struktura danych, która umożliwia przechowywanie unikatowych wartości dowolnego typu, niezależnie od tego, czy są to wartości pierwotne, czy odniesienia do obiektów. Zestaw można zadeklarować za pomocąES6
wbudowanego konstruktora zestawu w następujący sposób:const set = new Set([1, 2, 3, 4, 5]);
Podczas tworzenia zestawu za pomocą konstruktora Set nasz nowo utworzony obiekt set dziedziczy po
Set.prototype
. Ma to wiele pomocniczych metod i właściwości. Pozwala to łatwo wykonać następujące czynności:Przykład:
const set = new Set([1, 2, 3, 4, 5]); // checkout the size of the set console.log('size is: ' + set.size); // has method returns a boolean, true if the item is in the set console.log(set.has(1)); // add a number set.add(6); // delete a number set.delete(1); // iterate over each element using a callback set.forEach((el) => { console.log(el); }); // remove all the entries from the set set.clear();
Zgodność z przeglądarkami:
Wszystkie główne przeglądarki w pełni obsługują teraz zestawy z wyjątkiem IE, w których brakuje niektórych funkcji. Dokładne informacje można znaleźć w dokumentacji mdn .
źródło
Istnieją dwa problemy z używaniem gołych obiektów javascript do emulowania zestawów: po pierwsze, obiekt może mieć dziedziczoną właściwość, która wkręcałaby operator "in", a po drugie, w ten sposób można przechowywać tylko wartości skalarne, dzięki czemu zestaw obiektów nie jest możliwy. Dlatego realistyczna implementacja zestawów powinna zapewniać metody,
add
acontains
zamiastin
przypisań prostych i właściwości.źródło
set={};set[{x:1}]=123;alert(set[{z:99}])
Możesz wypróbować Buckets , jest biblioteką struktury danych javascript i ma wszystko, czego potrzebujesz do manipulowania zestawami.
źródło
Podstawowe tworzenie i używanie obiektu Set 🔷
let mySet = new Set() mySet.add(2) // Set {2} mySet.add(7) // Set {2, 7} mySet.add(7) // Set {2, 7} mySet.add('my text') // Set {2, 7, 'my text'} let myObj = { a: 1, b: 2 } mySet.add(myObj) // Set {2, 7, 'my text', {...}} mySet.has(2) // true mySet.has(myObj) // true mySet.size // 4
Iteracja
for (let item of mySet) console.log(item) // 2, 7, 'my text', {a:1, b:2} mySet.forEach(value => console.log(value)) // 2, 7, 'my text', {a:1, b:2}
Konwertuj na tablicę
var myArr = Array.from(mySet) // [2, 7, 'my text', {a:1, b:2}]
źródło