2

What is the simplest (one-line?) way to turn [1,2,3] into {1:0, 2:0, 3:0}?

Update: I would prefer to do it more "functional-style" (one line, with each or map etc)

7
  • 1
    There is no [1=>0, 2=>0, 3=>0]CommentedDec 18, 2012 at 14:44
  • thanks :) the question is fixedCommentedDec 18, 2012 at 14:45
  • 1
    Still incorrect. You are thinking of { 1: 0, 2: 0, 3: 0 }CommentedDec 18, 2012 at 14:46
  • Right, fixed again (currently in between Ruby and Javascript :)CommentedDec 18, 2012 at 14:47
  • 1
    Code golf is a much better place for this question.
    – Dennis
    CommentedDec 19, 2012 at 1:31

5 Answers 5

4

Array reduce method allows to pass second argument initialValue, to the method. You can send an object as initialValue and keep returning it through the iterations, assigning properties with key set to the current item of array. Beware of type coercion, property keys must be strings in JavaScript. So toString method will be invoked upon the items of array in this case.

var hash = array.reduce(function(obj,cur){ obj[cur]=0; return obj; },{}); 

demo

In form of one liner:

var hash = array.reduce(function (obj, cur) { obj[cur] = 0; return obj; }, {});

7
  • @Engineer: By your logic every script as big as it might be is a one liner :)CommentedDec 18, 2012 at 15:14
  • @gryzzly Thx, for the thorough explanation.
    – Engineer
    CommentedDec 18, 2012 at 15:17
  • @Engineer sure thing. Now I realise that this method will fail when the items of array aren't unique.CommentedDec 18, 2012 at 15:18
  • @Amberlamps I understand,what you mean. But in this case it's approved on-liner.
    – Engineer
    CommentedDec 18, 2012 at 15:23
  • 2
    @BreakPhreak This can be interesting for you.
    – Engineer
    CommentedDec 18, 2012 at 15:27
0

If you just want to convert your array to a key/value object, with all values set to 0 (as in your example) then you could use:

var hash = {}; [1,2,3].forEach(function(item) { hash[item] = 0; }); 
    0

    Even if this is against most best practices, this seems to be neat and foremost, a one-liner

    var foo = [1,2,3]; foo = eval('({' + foo.join(':0, ') + ':0 })' ); console.log( foo ); // Object {1=0, 2=0, 3=0} 
    6
    • +1 for creativity, although not recommending this solution at all :)CommentedDec 18, 2012 at 14:58
    • Actually, I don't see any real issue or danger in using eval in this instance. But in generell, I'd agree. Its more or less a thought experiment [And therefore, no reason to downvote @anonymous]
      – jAndy
      CommentedDec 18, 2012 at 15:04
    • at the minimum: measure performance of this method and think what will happen if you have many arrays like this, think of optimisation tools that won't be able to mangle variables inside of evalCommentedDec 18, 2012 at 15:06
    • @gryzzly: I don't really get your point. performance of what? eval is lightening fast, so is Array.prototype.join. Performance is the least worse thing for this snippet.
      – jAndy
      CommentedDec 18, 2012 at 15:11
    • @jAndy eval is known to be slower, three times slower in case of the code in question – jsperf.com/flat-array-to-object I like the creativity of your answer, but the comment about it being not a real issue is something I can't agree with. It's slower, it will mess with optimisation tools, and it is harder to read.CommentedDec 18, 2012 at 15:31
    0
    var arr = [1,2,3]; var result = {}; for (var i=0, l=arr.length; i<l;i++) { result[arr[i]] = 0; } 
    4
    • Neat, I would prefer to do it more "functional-style" (one line, with each or map etc)CommentedDec 18, 2012 at 14:46
    • 2
      Do not loop through an array with for ... inCommentedDec 18, 2012 at 14:54
    • @Amberlamps That's irrelevant here though, because the arrays are expected to not have gaps in them.
      – Ja͢ck
      CommentedDec 18, 2012 at 15:08
    • @Jack: This might be true, but why don´t you want to keep your code consistent? Just stick to the for(init;cond;inc) procedure.CommentedDec 18, 2012 at 15:12
    0

    Personally I don't see what's wrong with coding what you need:

    function objectWithKeysAndValue(keys, value) { var o = {}; for (var i = 0, n = keys.length; i != n; ++i) { o[keys[i]] = value; } return o; } console.log(objectWithKeysAndValue([1,2,3], 0); 

    Out of curiosity I ran this function against Engineer's answer and it's twice as fast!

    Results

      Start asking to get answers

      Find the answer to your question by asking.

      Ask question

      Explore related questions

      See similar questions with these tags.