如何重新考虑以下代码,以便不更改i
或initObj
?
// input: [{name: "Kevin"}, {name: "Bob"}]
// output: {"Kevin" : 0, "Bob" : 1}
var map = function(arr, property) {
var i = 0;
var initObj = {};
var m = arr.map(makeKv);
function makeKv(item) {
initObj[item[property]] = i++;
return initObj;
};
return m[0];
}
var x = map([{name: "Kevin"}, {name: "Bob"}], 'name');
alert(JSON.stringify(x, null, 4));
答案 0 :(得分:0)
我建议使用underscorejs,而不是自己写这样的低级别的东西。 http://underscorejs.org
答案 1 :(得分:0)
如果您想要{"Kevin" : 0, "Bob" : 1}
作为输出,那么.map()
是错误的工具。您希望使用.forEach
循环遍历数组,然后填写initObj
。
var map = function(arr, property) {
var initObj = {};
arr.forEach(makeKv);
function makeKv(item, index) {
initObj[item[property]] = index;
};
return initObj;
}
答案 2 :(得分:0)
想想你将如何在Haskell中做到这一点:
import Data.Map.Strict hiding (foldl)
data Person = Person { name :: String }
input :: [Person]
input = [Person "Kevin", Person "Bob"]
output :: Map String Int
output = foldl inductive empty $ zip input [0..]
where inductive result (person, index) = insert (name person) index result
同样,您可以在JavaScript中执行此操作:
var input = [{ name: "Kevin" }, { name: "Bob" }];
var output = input.reduce(inductive, {});
alert(JSON.stringify(output, null, 4));
function inductive(result, person, index) {
result[person.name] = index;
return result;
}

请注意,您不需要zip input [0..]
在JavaScript中,因为reduce
方法将index
元素作为第三个参数提供给inductive
函数
此外,我们仍在改变result
对象。您可以每次创建一个新的result
对象,将旧result
的值复制到新result
并添加新属性。然而,这将是非常低效的。