最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

arrays - How to create a map (object) from list of strings in Javascript - Stack Overflow

programmeradmin3浏览0评论

I have an array of many unique strings and I'd like, without looping if at all possible, to create a map object from it where the key for each element is a unique string and the value is defaulted to some arbitrary setting.

Is there a way I can do this in one line without looping? I.e. I want to go from

var colours = [ "Red", "Orange", "Yellow", "Green", "Blue", "Indigo", "Violet" ];

to

var colourMap = {
    "Red":    VAL,
    "Orange": VAL,
    "Yellow": VAL,
    "Green":  VAL,
    "Blue":   VAL,
    "Indigo": VAL,
    "Violet": VAL
};

I have an array of many unique strings and I'd like, without looping if at all possible, to create a map object from it where the key for each element is a unique string and the value is defaulted to some arbitrary setting.

Is there a way I can do this in one line without looping? I.e. I want to go from

var colours = [ "Red", "Orange", "Yellow", "Green", "Blue", "Indigo", "Violet" ];

to

var colourMap = {
    "Red":    VAL,
    "Orange": VAL,
    "Yellow": VAL,
    "Green":  VAL,
    "Blue":   VAL,
    "Indigo": VAL,
    "Violet": VAL
};
Share Improve this question asked Feb 3, 2014 at 15:13 Component 10Component 10 10.5k7 gold badges52 silver badges68 bronze badges 8
  • You mention in a ment below that you are looking to optimize this for performance since this code will be code repeatedly. First of all, can't you cache this in a variable in a higher scope? Unless the color list or VAL is going to be different every time there is no reason why you cannot. Second - are you sure performance is a problem? Most of the different techniques (for loop, reduce, forEach, underscore) have very similar performance and are unlikely to be your bottleneck. Profile before micro-optimizing! – George Mauer Commented Feb 3, 2014 at 15:39
  • @GeorgeMauer: Yes, good points which I will follow up. I suppose my underlying interest here was whether there is a way of doing this that is not O(n) - It sounds like there isn't. – Component 10 Commented Feb 3, 2014 at 15:46
  • JS hardly ever neatly follows those ptime predictions you learned in CS. depending on your needs, Object.create() could be a lot faster. – dandavis Commented Feb 3, 2014 at 15:47
  • I don't think its even theoretically possible for any operations on each element of an unordered array to be less than O(n). However, isn't O(n) the exact case that most algorithms try to get to? Once you're O(n) you're basically in "not a problem" territory. – George Mauer Commented Feb 3, 2014 at 15:49
  • sure it is, do some repetitive benchmarks in V8 or TraceMonkey and you'll see what i mean. if the routine is piled and not runtime optimized, the old rules apply. – dandavis Commented Feb 3, 2014 at 15:50
 |  Show 3 more ments

3 Answers 3

Reset to default 5

Assuming your browser requirements support Array.prototype.reduce

colours.reduce(function(obj, c){ 
  obj[c] = "VAL";
  return obj;
}, {})

or if you're ok with being a jerk and using syntax most js devs aren't even aware exists

colours.reduce(function(obj, c){ return (obj[c] = "VAL", obj) }, {})

If you really want to skip loops altogether (Including functions like map), this works:

JSON.parse('{"'+colours.join('":"VAL", "')+'":"VAL"}');

This builds a JSON string, then parses it.

However, I wouldn't use this function. It's ugly, inefficient, hard to maintain, uses loops "under the hood", and it's generally bad form. (I'm not even gonna bother with eval instead of JSON. eval === evil).

Go for something like map instead:

var colours = [ "Red", "Orange", "Yellow", "Green", "Blue", "Indigo", "Violet" ];
var colourMap = {};
colours.forEach(function(c){
    colourMap[c] = "VAL";
});

Yes, it's looping through the colours, but it's more efficient, and easier to understand.

Regarding performance:

map and reduce seem to be similar in execution speed (reduce is slightly faster), in Google Chrome.

You can do it with jQuery:

colourMap = $.map(colours, function(e){
  return { e: "VAL" };
});

or with Underscore:

var colourMap = {};
_.each(some_object_array, function(val) {
  colourMap[val] = "VAL";
});

Or even better (Thanks to George Mauer):

_.object(_.map(colourMap, function(c) { return [c, "VAL"] }))
发布评论

评论列表(0)

  1. 暂无评论