Javascript-форум (https://javascript.ru/forum/)
-   Ваши сайты и скрипты (https://javascript.ru/forum/project/)
-   -   Реализация Set и Map (https://javascript.ru/forum/project/25978-realizaciya-set-i-map.html)

FINoM 21.02.2012 17:10

Реализация Set и Map
 
Снова решил кое-что сделать из чистого интереса. Было интересно, зачем мозилла реализовала нативную имплементацию конструкторов Map и Set и проверить, насколько сложно было бы это реализовать своими силами. Очень просто.

https://developer.mozilla.org/en/Jav...al_Objects/Set
https://developer.mozilla.org/en/Jav...al_Objects/Map
var Set = function Set() {
    var values = [];
    return {
        add: function(value) {
            var index = values.indexOf(value);
            if (!~index) {
                values.push(value);
            }
        },
        'delete': function(value) {
            var index = values.indexOf(value);
            if (~index) {
                values.splice(index, 1);
            }
        },
        has: function(value) {
            var index = values.indexOf(value);
            return !!~index;

        }
    }
}


var set = new Set;
var object = {
    a: 4
}
set.add(object)
console.log(set.has(object));
set.add(object)
console.log(set.has(object));
set.delete(object);
console.log(set.has(object));​

http://jsfiddle.net/finom/EvWTN/

var Map = function Map() {}
Map.prototype = {
    _keys: [],
    _values: [],
    
    //is set contains those things:
    _strange: {
        pz: undefined, //positive Zero
        nz: undefined, //negative Zero
        nan: undefined //NaN
    },
    
    _isStrange: function( key ){
        switch( true ) {
            case isNaN(key) && typeof key === 'number': return 'nan';
            case key === 0 && 1/key === Infinity  : return 'pz';
            case key === 0 && 1/key === -Infinity : return 'nz';
        }
    },
    
    set: function(key, value) {
        var index, strange = this._isStrange( key );
        if( strange ) { console.log(strange )
            this._strange[ strange ] = value;
            return;
        }
        console.log(key, value)
        index = this._keys.indexOf(key);
        if (!~index) {
            this._keys.push(key);
            this._values.push(value);
        } else {
            this._values[index] = value;
        }
    },
    
    get: function(key) {
        var index, strange = this._isStrange( key );
        if( strange ) {
            return this._strange[ strange ];
        }
        
        index = this._keys.indexOf(key);
        return this._values[index];
    },
    
    has: function(key) {
        var index, strange = this._isStrange( key );
        if( strange ) {
            return this._strange[ strange ] !== undefined;
        }
        
        index = this._keys.indexOf(key);
        return !!~index;
    },
    'delete': function(key) {
        var index, strange = this._isStrange( key );
        if( strange ) {
            this._strange[ strange ] = undefined;
        }
        
        index = this._keys.indexOf(key);
        if (~index) {
            this._keys.splice(index, 1);
            this._values.splice(index, 1);
        }
    },
    
}
var map = new Map
var pz =0;
var nz = -0;

map.set(pz , 10);
map.set(nz , 12);
map.set(NaN, 14);


console.log(map.get(pz ), map.has(pz ), map.get(nz ), map.has(nz ))
map.delete(nz )
console.log(map.get(NaN), map.has(NaN), map.get(nz ), map.has(nz ))​​

http://jsfiddle.net/finom/GwRy2/5/

FINoM 21.02.2012 17:22

Только вот не работает с NaN и не различает +0 и -0.
И да, упустил еще пару моментов, например, map.get() возвращает -1 вместо undefined, если отсутствует такой ключ, мот еще что-то.

B@rmaley.e><e 21.02.2012 19:53

Нативная реализация, видимо, нужна для скорости. Реализовать-то эти структуры на JS ничего не стоит.

FINoM 21.02.2012 20:12

Цитата:

Сообщение от B@rmaley.e><e
Нативная реализация, видимо, нужна для скорости.

Не уверен, что разница будет существенной.

Nekromancer 21.02.2012 21:51

Map и Set части стандарта ES6. В SpiderMonkey потихоньку имплементируют всё новые возможности из ES6. Можно сказать конечно, что и в ES6 можно с лёгкостью будет написать такие классы, но если их ввели в стандарт - значит нужно. Это всё таки язык высокого уровня, а не например как плюсы, в которых постоянно нужно подключать библиотеки.

FINoM 22.02.2012 03:12

Переписал Map. Теперь он работает с NaN и различает +0 и -0.


Часовой пояс GMT +3, время: 09:14.