17

I've got an array of channels that I want to transform into a single object (channelSettings) with a true / false property for each channel.

I've got it working using the below code but it seems verbose. Is there are way to do it without the "temp" var? If I can get ride of that, then I could get ride of the self executing function as well.

var channels = ["TV", "Billboard", "Spot TV"];


var channelSettings = function() {
    var temp = {};

    channels.map(function(itm, i, a) {
        var channel = itm.toLowerCase().replace(" ", "");
        temp[channel] = false;
    });

    return temp;
}();

I guess I'm trying to get the map function to return an object with properties instead of an array. Is this possible? Is it mis-guided? Suggestions?

This is what I'm hoping it looks like in the end:

var channels = ["TV", "Billboard", "Spot TV"];

var channelSettings = channels.map(function(itm, i, a) {
        var channel = itm.toLowerCase().replace(" ", "");
        return ????;
});
2
  • 1
    It may be a bit verbose, but it's also clear. I'd vote to leave it as it is. Commented Jun 13, 2012 at 0:38
  • just wanna add that the keys can have spaces and capital letters. for better consistency. Commented Mar 17, 2020 at 14:36

3 Answers 3

28

Use a .reduce() function instead.

var channelSettings = channels.reduce(function(obj, itm) {
        var channel = itm.toLowerCase().replace(" ", "");
        obj[channel] = false;

        return obj;
}, {});

DEMO: http://jsfiddle.net/MjW9T/


The first parameter references the previously returned item, except for the first iteration, where it references either the first item in the Array, or the seeded item, which we provided as an empty object.

The second parameter references the current value in the Array. As long as we always return obj, the first parameter will always be that object, as will the final return value.

Sign up to request clarification or add additional context in comments.

Comments

5

The map function takes an array, and returns an array. Nothing else. But you can use reduce:

var settings = ["TV", "Billboard", "Spot TV"].reduce(function(obj, item) {
   obj[item.toLowerCase().replace(" ", "")] = false; // probably too concise
   return obj // yay, we can skip a semi-colon here :-P
}, {});

Well, "am not i am" beat me to it, but anyway:
map not only returns arrays, but also only returns arrays of the same length as the original. It's meant for transforming one array's values 1:1 into a new array. reduce is meant to "reduce an array to a single value". Hence its use here.

If you use a straight for loop or the forEach method to add properties to an object, you do need to declare that object. So, no, you can't do without temp in your code (unless you use reduce instead of a loop).

More information on MDN:

  1. map: https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/map
  2. reduce: https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/Reduce

3 Comments

and an excellent explanation here too! (I wouldn't have to defend my green check determination in court..) many thx!
@RobG Ah, MDN links - I completely forgot to add those. Thanks for the edit
I ended up using a more clear version. var key =item.toLowerCase().replace(" ", ""); obj[key] = false; return obj
0

hmm.. looks like wrapping it in a function like this would do it.

function toObject(arr) {
  var rv = {};
  for (var i = 0; i < arr.length; ++i)
    if (arr[i] !== undefined) rv[arr[i]] = true;
  return rv;
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.