ES6 özellikli bir ortamda (ihtiyacınız olan ES6 özelliklerine sahip belirli bir tarayıcı veya ortamınız için ES6 kodunu aktarırken) node.js programlıyorsanız, ES6'da Set
yerleşik nesneyi kullanabilirsiniz . Çok güzel yeteneklere sahiptir ve ortamınızda olduğu gibi kullanılabilir.
ES5 ortamındaki birçok basit şey için, bir Nesne kullanmak çok iyi çalışır. Eğer obj
sizin nesnedir ve A
siz sette çalışmak istediğiniz değere sahip bir değişken olduğunu, o zaman bu yapabilirsiniz:
Başlatma kodu:
// create empty object
var obj = {};
// or create an object with some items already in it
var obj = {"1":true, "2":true, "3":true, "9":true};
Soru 1: mi A
listedeki:
if (A in obj) {
// put code here
}
Soru 2: Varsa, listeden 'A'yı silin:
delete obj[A];
Soru 3: Zaten orada değilse listeye 'A' ekleyin
obj[A] = true;
Tamlık için A
, listede olup olmadığının testi bununla biraz daha güvenlidir:
if (Object.prototype.hasOwnProperty.call(obj, A))
// put code here
}
yerleşik yöntemler ve / veya özellik gibi temel nesneler arasındaki potansiyel çakışma nedeniyle constructor
.
ES6'daki kenar çubuğu: ECMAScript 6'nın geçerli çalışma sürümü veya ES 2015 adı verilen bir şey yerleşik bir Set nesnesine sahiptir . Şimdi bazı tarayıcılarda uygulanmaktadır. Tarayıcı kullanılabilirlik süresini bir şekilde değiştiği için için, çizgiyi bakabilirsiniz Set
içinde bu ES6 uyumluluk tablosunun tarayıcı kullanılabilirlik için mevcut durumunu görmek için.
Yerleşik Set nesnesinin bir avantajı, tüm anahtarları Object gibi bir dizeye zorlamamasıdır, böylece hem 5 hem de "5" tuşlarına ayrı anahtarlar olarak sahip olabilirsiniz. Ve hatta, dizeleri dönüştürmeden Nesneleri doğrudan kümede kullanabilirsiniz. İşte Set nesnesindeki bazı yetenekleri ve MDN belgelerini açıklayan bir makale .
Şimdi ES6 set nesnesi için bir çoklu dolgu yazdım, böylece şimdi kullanmaya başlayabilirsiniz ve tarayıcı destekliyorsa otomatik olarak yerleşik set nesnesine erteleyecektir. Bunun avantajı, IE7'ye kadar çalışacak ES6 uyumlu kod yazmanızdır. Ancak, bazı dezavantajları var. ES6 set arayüzü, ES6 yineleyicilerinden yararlanır, böylece sizin gibi şeyler yapabilirsiniz for (item of mySet)
ve sizin için otomatik olarak set boyunca tekrar eder. Ancak, bu tür bir dil özelliği çok dolgu ile uygulanamaz. Yeni ES6 dilleri özelliklerini kullanmadan bir ES6 setini yine de yineleyebilirsiniz, ancak açıkçası yeni dil özellikleri olmadan, aşağıda eklediğim diğer set arayüzü kadar uygun değildir.
Her ikisine de baktıktan sonra hangisinin sizin için en iyi olduğuna karar verebilirsiniz. ES6 set çoklu dolgusu burada: https://github.com/jfriend00/ES6-Set .
FYI, kendi testlerimde, Firefox v29 Set uygulamasının spesifikasyonun mevcut taslağında tam olarak güncel olmadığını fark ettim. Örneğin, .add()
özellik açıklamaları ve çoklu dolum desteklediğim gibi yöntem çağrılarını zincirleyemezsiniz . Bu, henüz tamamlanmadığı için muhtemelen hareket halindeki bir spesifikasyon meselesidir.
Önceden Oluşturulmuş Küme nesneleri: Herhangi bir tarayıcıda kullanabileceğiniz bir kümede çalışma yöntemleri olan önceden oluşturulmuş bir nesne istiyorsanız, farklı türlerde kümeler uygulayan bir dizi farklı önceden oluşturulmuş nesne kullanabilirsiniz. Bir set nesnesinin temellerini uygulayan küçük bir kod olan bir miniSet vardır. Ayrıca daha zengin özelliklere sahip bir set nesnesi ve bir Sözlük (her bir anahtar için bir değer depolayalım / alalım) ve bir ObjectSet (bir nesne kümesi tutalım - ya JS nesneleri veya her biri için benzersiz bir anahtar üreten bir işlev veya ObjectSet anahtarı sizin için oluşturur).
İşte miniSet için kod kopyası (en yukarı güncel kodudur var github burada ).
"use strict";
//-------------------------------------------
// Simple implementation of a Set in javascript
//
// Supports any element type that can uniquely be identified
// with its string conversion (e.g. toString() operator).
// This includes strings, numbers, dates, etc...
// It does not include objects or arrays though
// one could implement a toString() operator
// on an object that would uniquely identify
// the object.
//
// Uses a javascript object to hold the Set
//
// This is a subset of the Set object designed to be smaller and faster, but
// not as extensible. This implementation should not be mixed with the Set object
// as in don't pass a miniSet to a Set constructor or vice versa. Both can exist and be
// used separately in the same project, though if you want the features of the other
// sets, then you should probably just include them and not include miniSet as it's
// really designed for someone who just wants the smallest amount of code to get
// a Set interface.
//
// s.add(key) // adds a key to the Set (if it doesn't already exist)
// s.add(key1, key2, key3) // adds multiple keys
// s.add([key1, key2, key3]) // adds multiple keys
// s.add(otherSet) // adds another Set to this Set
// s.add(arrayLikeObject) // adds anything that a subclass returns true on _isPseudoArray()
// s.remove(key) // removes a key from the Set
// s.remove(["a", "b"]); // removes all keys in the passed in array
// s.remove("a", "b", ["first", "second"]); // removes all keys specified
// s.has(key) // returns true/false if key exists in the Set
// s.isEmpty() // returns true/false for whether Set is empty
// s.keys() // returns an array of keys in the Set
// s.clear() // clears all data from the Set
// s.each(fn) // iterate over all items in the Set (return this for method chaining)
//
// All methods return the object for use in chaining except when the point
// of the method is to return a specific value (such as .keys() or .isEmpty())
//-------------------------------------------
// polyfill for Array.isArray
if(!Array.isArray) {
Array.isArray = function (vArg) {
return Object.prototype.toString.call(vArg) === "[object Array]";
};
}
function MiniSet(initialData) {
// Usage:
// new MiniSet()
// new MiniSet(1,2,3,4,5)
// new MiniSet(["1", "2", "3", "4", "5"])
// new MiniSet(otherSet)
// new MiniSet(otherSet1, otherSet2, ...)
this.data = {};
this.add.apply(this, arguments);
}
MiniSet.prototype = {
// usage:
// add(key)
// add([key1, key2, key3])
// add(otherSet)
// add(key1, [key2, key3, key4], otherSet)
// add supports the EXACT same arguments as the constructor
add: function() {
var key;
for (var i = 0; i < arguments.length; i++) {
key = arguments[i];
if (Array.isArray(key)) {
for (var j = 0; j < key.length; j++) {
this.data[key[j]] = key[j];
}
} else if (key instanceof MiniSet) {
var self = this;
key.each(function(val, key) {
self.data[key] = val;
});
} else {
// just a key, so add it
this.data[key] = key;
}
}
return this;
},
// private: to remove a single item
// does not have all the argument flexibility that remove does
_removeItem: function(key) {
delete this.data[key];
},
// usage:
// remove(key)
// remove(key1, key2, key3)
// remove([key1, key2, key3])
remove: function(key) {
// can be one or more args
// each arg can be a string key or an array of string keys
var item;
for (var j = 0; j < arguments.length; j++) {
item = arguments[j];
if (Array.isArray(item)) {
// must be an array of keys
for (var i = 0; i < item.length; i++) {
this._removeItem(item[i]);
}
} else {
this._removeItem(item);
}
}
return this;
},
// returns true/false on whether the key exists
has: function(key) {
return Object.prototype.hasOwnProperty.call(this.data, key);
},
// tells you if the Set is empty or not
isEmpty: function() {
for (var key in this.data) {
if (this.has(key)) {
return false;
}
}
return true;
},
// returns an array of all keys in the Set
// returns the original key (not the string converted form)
keys: function() {
var results = [];
this.each(function(data) {
results.push(data);
});
return results;
},
// clears the Set
clear: function() {
this.data = {};
return this;
},
// iterate over all elements in the Set until callback returns false
// myCallback(key) is the callback form
// If the callback returns false, then the iteration is stopped
// returns the Set to allow method chaining
each: function(fn) {
this.eachReturn(fn);
return this;
},
// iterate all elements until callback returns false
// myCallback(key) is the callback form
// returns false if iteration was stopped
// returns true if iteration completed
eachReturn: function(fn) {
for (var key in this.data) {
if (this.has(key)) {
if (fn.call(this, this.data[key], key) === false) {
return false;
}
}
}
return true;
}
};
MiniSet.prototype.constructor = MiniSet;