Javascript:如何将对象数组转换为具有排序的唯一数组的对象?

Dou*_*uch 5 javascript

拥有具有这种结构的数据:

$input = [ { animal: 'cat', name: 'Rocky', value: 1 },
           { animal: 'cat', name: 'Spot',  value: 2 },
           { animal: 'dog', name: 'Spot',  value: 3 } ];
Run Code Online (Sandbox Code Playgroud)

需要最快的方法来转换为这种格式:

$output = { animal: [ 'cat', 'dog' ],
            name: [ 'Rocky', 'Spot' ],
            value: [ 1, 2, 3 ] };
Run Code Online (Sandbox Code Playgroud)

输出的键应该等于输入中每个对象中的每个键。并且输出值应该是具有排序的唯一值的数组。我找到了几种使用嵌套循环的方法,但比我想要的要慢。输入数组有 30,000 个元素,每个对象有 8 个键,我所能做的最好的事情是 Chrome 中的 300 毫秒。想降到 100 毫秒。有没有使用 map 或 reduce 更快的方法?

cli*_*ity 2

这是一种方法。

$input = [ { animal: 'cat', name: 'Rocky', value: 1 },
           { animal: 'cat', name: 'Spot',  value: 2 },
           { animal: 'dog', name: 'Spot',  value: 3 } ];

$output = {animal:{},name:{},value:{}};

$input.forEach(function(v,i) { 
    $output.animal[v.animal] = 1;
    $output.name[v.name] = 1;
    $output.value[v.value] = 1;
});

$output.animal = Object.keys($output.animal);
$output.name = Object.keys($output.name);
$output.value = Object.keys($output.value);
Run Code Online (Sandbox Code Playgroud)

它可以避免每次都测试每个数组。您可以进行性能比较,看看是否有帮助。

实例: http: //jsfiddle.net/TJVtj/1/


如果您不想对密钥进行硬编码,则可以使解决方案变得通用。

var keys = Object.keys($input[0]),
    $output = {};

keys.forEach(function(v) {
    $output[v] = {};
});

$input.forEach(function(v) {
    keys.forEach(function(vv) {
        $output[vv][v[vv]] = 1;
    });
});

keys.forEach(function(v) {
    $output[v] = Object.keys($output[v]);
});
Run Code Online (Sandbox Code Playgroud)

实例: http: //jsfiddle.net/TJVtj/2/

警告。所有值都将是字符串,因为它们是作为对象键获取的。