somewhat OT: creating a lookup hash in JS

113 views
Skip to first unread message

Felipe Gasper

unread,
Oct 30, 2012, 5:50:13 PM10/30/12
to nod...@googlegroups.com
(Sorry, this is slightly OT.)

var the_array = ["foo", "bar", "baz", "qux"];

//Is there a simpler way to do the following than what�s here?
var the_lookup = {};
the_array.forEach( function(i) { the_lookup.i = true } );

========

In Perl this is easy:
my @array = qw(foo bar baz qux);
my %lookup = map { $_ => 1 } @array;


Anything of the sort coming in JS, does anyone know? Maybe in some of
the newer ES5 goodies?

-FG

mscdex

unread,
Oct 30, 2012, 6:25:48 PM10/30/12
to nodejs
On Oct 30, 5:50 pm, Felipe Gasper <fel...@felipegasper.com> wrote:
> Anything of the sort coming in JS, does anyone know? Maybe in some of
> the newer ES5 goodies?

Does this help?: https://github.com/joyent/node/wiki/ECMA-5-Mozilla-Features-Implemented-in-V8

Felipe Mobus

unread,
Oct 30, 2012, 6:36:28 PM10/30/12
to nod...@googlegroups.com
You could use ES5's array.reduce() method, but it's gonna be a bit ugly

[1,2,3,4,5,6,7,8].reduce(function(prev, cur) {
prev[cur] = (cur % 2) == 0;
return prev;
}, {})
> --
> Job Board: http://jobs.nodejs.org/
> Posting guidelines: https://github.com/joyent/node/wiki/Mailing-List-Posting-Guidelines
> You received this message because you are subscribed to the Google
> Groups "nodejs" group.
> To post to this group, send email to nod...@googlegroups.com
> To unsubscribe from this group, send email to
> nodejs+un...@googlegroups.com
> For more options, visit this group at
> http://groups.google.com/group/nodejs?hl=en?hl=en



--
Felipe Mobus
http://fmobus.wait4.org

Felipe Mobus

unread,
Oct 30, 2012, 6:42:22 PM10/30/12
to nod...@googlegroups.com
pardon me for the (cur % 2) == 0 part, completely unnecessary to your case

Trevor Norris

unread,
Oct 30, 2012, 7:02:37 PM10/30/12
to nod...@googlegroups.com
To supplement what mscdex has already posted, here are two more articles:


You'l want to check out Set's. Enable them with `node --harmony` at runtime. Also, v8 doesn't support Set initialization with an Array. So you'll have to use .add() for every element. But they are about 6 times faster than using an Object lookup. Sort of like the following:

var the_set = new Set();
the_array.forEach(function(i) { the_set.add(i); });

As a side note, your syntax is incorrect. The forEach statement should look like the following:

the_array.forEach(function(i) { the_lookup[i] = true; });

Ted Young

unread,
Oct 30, 2012, 7:35:43 PM10/30/12
to nod...@googlegroups.com
var MAX = 1000000;
var arr = [], obj = {}, obj2 = {},foo, start;

for(i = 0; i < MAX; i++){
arr.push(i.toString());
}

start = Date.now();
arr.reduce(function(obj2,i){
obj2[i] = true;
return obj2;
},obj2);
console.log('reduce',Date.now() - start);

start = Date.now();
arr.forEach(function(i){
obj[i] = true;
});
console.log('forEach',Date.now() - start);
var MAX = 1000000;
var arr = [], obj = {}, obj2 = {},foo, start;

for(i = 0; i < MAX; i++){
arr.push(i.toString());
}

start = Date.now();
arr.reduce(function(obj2,i){
obj2[i] = true;
return obj2;
},obj2);
console.log('reduce',Date.now() - start);

start = Date.now();
arr.forEach(function(i){
obj[i] = true;
});
console.log('forEach',Date.now() - start);
var MAX = 1000000;
var arr = [], obj = {}, obj2 = {},foo, start;

for(i = 0; i < MAX; i++){
arr.push(i.toString());
}

start = Date.now();
arr.reduce(function(obj2,i){
obj2[i] = true;
return obj2;
},obj2);
console.log('reduce',Date.now() - start);

start = Date.now();
arr.forEach(function(i){
obj[i] = true;
});
console.log('forEach',Date.now() - start);
A quick speed test, comparing forEach and reduce:

var arr = [], obj = {}, obj2 = {}, start;
var MAX = 1000000;

for(i = 0; i < MAX; i++){
  arr.push(i.toString());
}

// test reduce
start = Date.now();
arr.reduce(function(obj,i){
    obj[i] = true;
    return obj;
},obj);
console.log('reduce',Date.now() - start);

// test forEach
start = Date.now();
arr.forEach(function(i){
    obj2[i] = true;
});
console.log('forEach',Date.now() - start);
var MAX = 1000000;
var arr = [], obj = {}, obj2 = {},foo, start;

for(i = 0; i < MAX; i++){
arr.push(i.toString());
}

start = Date.now();
arr.reduce(function(obj2,i){
obj2[i] = true;
return obj2;
},obj2);
console.log('reduce',Date.now() - start);

start = Date.now();
arr.forEach(function(i){
obj[i] = true;
});
console.log('forEach',Date.now() - start);
var MAX = 1000000;
var arr = [], obj = {}, obj2 = {},foo, start;

for(i = 0; i < MAX; i++){
arr.push(i.toString());
}

start = Date.now();
arr.reduce(function(obj2,i){
obj2[i] = true;
return obj2;
},obj2);
console.log('reduce',Date.now() - start);

start = Date.now();
arr.forEach(function(i){
obj[i] = true;
});
console.log('forEach',Date.now() - start);


results are:

in node:
reduce 169
forEach 147

in node if you reverse the order:
forEach 170
reduce 145

in firefox:
reduce 956
forEach 1906

reversed in firefox:
forEach 2057
reduce 944

If this is for the browser, reduce seems twice as fast in firefox.  In node they appear equivalent. 

forEach is about as concise as it gets, but hey, one line of code ain't bad. :)

Ted

Rick Waldron

unread,
Oct 31, 2012, 11:33:29 AM10/31/12
to nod...@googlegroups.com
On Tue, Oct 30, 2012 at 7:02 PM, Trevor Norris <trev....@gmail.com> wrote:
To supplement what mscdex has already posted, here are two more articles:


You'l want to check out Set's. Enable them with `node --harmony` at runtime. Also, v8 doesn't support Set initialization with an Array. So you'll have to use .add() for every element. But they are about 6 times faster than using an Object lookup. Sort of like the following:

var the_set = new Set();
the_array.forEach(function(i) { the_set.add(i); });


Ugh, it's too bad v8's implementation is outdated, because the correct way to do exactly this is:

var set = new Set(the_array); // creates a unique set with lookup API for free! yay!

Rick


 

As a side note, your syntax is incorrect. The forEach statement should look like the following:

the_array.forEach(function(i) { the_lookup[i] = true; });


On Tuesday, October 30, 2012 2:50:25 PM UTC-7, Felipe Gasper wrote:
(Sorry, this is slightly OT.)

var the_array = ["foo", "bar", "baz", "qux"];

//Is there a simpler way to do the following than what�s here?
var the_lookup = {};
the_array.forEach( function(i) { the_lookup.i = true } );

========

In Perl this is easy:
my @array = qw(foo bar baz qux);
my %lookup = map { $_ => 1 } @array;


Anything of the sort coming in JS, does anyone know? Maybe in some of
the newer ES5 goodies?

-FG

--
Reply all
Reply to author
Forward
0 new messages