diff --git a/README.md b/README.md index f5246c0..0b87031 100644 --- a/README.md +++ b/README.md @@ -62,6 +62,10 @@ Returns the number of key/value pairs in the hash table. `cb` is an iterator function that will be called with each key/value pair like `cb.call(c, key, value)`, if context is not provided, the global. +### `find ( pred, context )` + +`pred` is a predicate function that will be called with each key/value pair like `pred.call(c, key, value)` until `pred` returns true. Returns the value for the first key/value pair to which `pred` returned true, otherwise undefined. If context is not provided, the global. + ### `keys ()` Will return an array of the keys stored in the hashtable. diff --git a/index.js b/index.js index 531d930..6cb0bda 100644 --- a/index.js +++ b/index.js @@ -1 +1,11 @@ -module.exports = require('./build/Release/native').HashTable; +var HashTable = require('./build/Release/native.node').HashTable; +HashTable.prototype.toJSON = function() { + var ret = {}; + this.forEach(function(key, value) { + ret[String(key)] = value; + }); + + return ret; +}; + +module.exports = HashTable; diff --git a/package.json b/package.json index d18d055..7fec4c8 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "hashtable", - "version": "2.0.1", + "version": "2.0.2", "description": "Native HashTable and ES6 compatible Map for Node.js", "main": "./index.js", "keywords": [ diff --git a/src/hashtable.cpp b/src/hashtable.cpp index 461ff22..5f952fc 100644 --- a/src/hashtable.cpp +++ b/src/hashtable.cpp @@ -22,6 +22,7 @@ void HashTable::init(Local target) { Nan::SetPrototypeMethod(constructor, "reserve", Reserve); Nan::SetPrototypeMethod(constructor, "max_load_factor", MaxLoadFactor); Nan::SetPrototypeMethod(constructor, "forEach", ForEach); + Nan::SetPrototypeMethod(constructor, "find", Find); target->Set(Nan::New("HashTable").ToLocalChecked(), constructor->GetFunction()); } @@ -308,6 +309,44 @@ NAN_METHOD(HashTable::ForEach) { return; } +NAN_METHOD(HashTable::Find) { + Nan::HandleScope scope; + + HashTable *obj = Nan::ObjectWrap::Unwrap(info.This()); + + if (info.Length() < 1 || !info[0]->IsFunction()) { + Nan::ThrowTypeError("Wrong arguments"); + return; + } + Local predicate = info[0].As(); + + Local ctx; + if (info.Length() > 1 && info[1]->IsObject()) { + ctx = info[1]->ToObject(); + } else { + ctx = Nan::GetCurrentContext()->Global(); + } + + const unsigned argc = 3; + Local argv[argc]; + argv[2] = info.This(); + + MapType::const_iterator itr = obj->map.begin(); + + while (itr != obj->map.end()) { + argv[0] = Local::New(Isolate::GetCurrent(), *itr->first); + argv[1] = Local::New(Isolate::GetCurrent(), *itr->second); + if (predicate->Call(ctx, argc, argv)->BooleanValue()) { + info.GetReturnValue().Set(argv[1]); + return; + } + itr++; + } + + info.GetReturnValue().Set(Nan::Undefined()); + return; +} + extern "C" void init (Local target) { Nan::HandleScope scope; diff --git a/src/hashtable.h b/src/hashtable.h index 2392211..914b039 100644 --- a/src/hashtable.h +++ b/src/hashtable.h @@ -3,7 +3,7 @@ #include #include -#ifdef __APPLE__ +#if defined __APPLE__ && __cplusplus < 201103L #include #define unordered_map std::tr1::unordered_map #else @@ -62,6 +62,9 @@ class HashTable : public Nan::ObjectWrap { // hashTable.forEach(function (key, value) {...}, context) : undefined static NAN_METHOD(ForEach); + + // hashTable.find(function (key, value) {...}, context) : value + static NAN_METHOD(Find); }; #endif diff --git a/src/v8_value_hasher.h b/src/v8_value_hasher.h index 8f6e0a8..f03985f 100644 --- a/src/v8_value_hasher.h +++ b/src/v8_value_hasher.h @@ -4,7 +4,7 @@ #include #include #include -#ifdef __APPLE__ +#if defined __APPLE__ && __cplusplus < 201103L #include #define hash std::tr1::hash #else