映射JSON数组

时间:2013-11-18 20:27:56

标签: javascript functional-programming

如何重新考虑以下代码,以便不更改iinitObj

// 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));

3 个答案:

答案 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;
}

DEMO:http://jsfiddle.net/FgdSj/9/

答案 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并添加新属性。然而,这将是非常低效的。

相关问题