17

我有一组通道,我想将它们转换为单个对象(channelSettings),每个通道都有一个 true / false属性。

我已经使用下面的代码让它工作了,但它看起来很冗长。没有“temp”变量有没有办法做到这一点?如果我能驾驭它,那么我也可以驾驭自执行功能。

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;
}();

我想我正试图让 map 函数返回一个带有属性而不是数组的对象。这可能吗?是不是被误导了?建议?

这就是我希望它最终的样子:

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

var channelSettings = channels.map(function(itm, i, a) {
        var channel = itm.toLowerCase().replace(" ", "");
        return ????;
});
4

3 回答 3

28

改用.reduce()函数。

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

        return obj;
}, {});

演示:http: //jsfiddle.net/MjW9T/


第一个参数引用先前返回的项,但第一次迭代除外,它引用 Array 中的第一项或我们作为空对象提供的种子项。

第二个参数引用数组中的当前值。只要我们总是 return obj,第一个参数总是那个对象,最终的返回值也是如此。

于 2012-06-13T00:40:49.603 回答
4

map函数接受一个数组,并返回一个数组。没有其他的。但你可以使用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
}, {});

好吧,“我不是”打败了我,但无论如何:
map不仅返回数组,而且只返回与原始数组长度相同的数组。它用于将一个数组的值 1:1 转换为一个新数组。reduce旨在“将数组减少为单个值”。因此在这里使用它。

如果您使用直接for循环或forEach方法向对象添加属性,则确实需要声明该对象。所以,不,你不能temp在你的代码中没有(除非你使用reduce而不是循环)。

有关 MDN 的更多信息:

  1. 地图:https ://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/map
  2. 减少:https ://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/Reduce
于 2012-06-13T00:42:30.257 回答
0

嗯..看起来像把它包装在这样的函数中就可以了。

function toObject(arr) {
  var rv = {};
  for (var i = 0; i < arr.length; ++i)
    if (arr[i] !== undefined) rv[arr[i]] = true;
  return rv;
}
于 2012-06-13T00:38:34.380 回答