5

このような構造を持つデータを持っています:

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

この形式に変換するための最速の方法が必要です:

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

出力には、入力からの各オブジェクトの各キーと等しいキーが必要です。出力値は、並べ替えられた一意の値を持つ配列である必要があります。ネストされたループを使用してそれを行う方法をいくつか見つけましたが、思ったよりも遅くなりました。オブジェクトごとに 8 つのキーを持つ入力配列に 30,000 の要素を使用すると、Chrome で 300 ミリ秒を達成できました。100msまで落としたい。map または reduce を使用したより高速な方法はありますか?

4

5 に答える 5

3

最新のブラウザーのさらに別の方法:

$input.reduce(function(acc, obj) {
  Object.keys(obj).forEach(function(k) {
    acc[k] = (acc[k] || []).concat(obj[k])
  })
  return acc
},{})
于 2015-03-20T23:12:59.200 に答える
2

これが1つの方法です。

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

毎回各アレイをテストする必要がなくなります。パフォーマンスを比較して、それが役立つかどうかを確認できます。

実例: 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]);
});

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

警告。オブジェクトキーとしてフェッチされるため、すべての値は文字列になります。

于 2012-05-07T20:55:59.783 に答える
0
function inArray(needle, haystack) {
    var length = haystack.length;
    for(var i = 0; i < length; i++) {
        if(haystack[i] == needle) return true;
    }
    return false;
}

上記の機能は、重複をチェックするために使用されます

$output={};
for(i=0; i< $input.length; i++)
{
    if(!$output.animal) $output.animal=[];
    if(!$output.name) $output.name=[];
    if(!$output.value) $output.value=[];
    var ani=$input[i];
    if(ani.animal && !inArray(ani.animal, $output.animal)) $output.animal.push(ani.animal);
    if(ani.name && !inArray(ani.name, $output.name)) $output.name.push(ani.name);
    if(ani.value) $output.value.push(ani.value);
}

デモ。

于 2012-05-07T21:13:08.803 に答える
0

// オブジェクトがすべて同じキーを持っていることがわからない場合は、それぞれを調べる必要があります-

var output= {},
input= [{
    animal:'cat', name:'Rocky', value:1
},{
    animal:'cat', name:'Spot', value:2
},{
    animal:'dog', name:'Spot', value:3
}];
input.forEach(function(itm){
    for(var p in itm){
        if(itm.hasOwnProperty(p)){
            if(!output[p]) output[p]= [];
            if(output[p].indexOf(itm[p])== -1) output[p].push(itm[p]);
        }
    }
});

Run.expose(output)// nonstandard object to string method

// returned value: (String)
{
    animal:[
        'cat',
        'dog'
    ],
    name:[
        'Rocky',
        'Spot'
    ],
    value:[
        1,
        2,
        3
    ]
}
于 2012-05-07T21:46:46.120 に答える
-1

アンダースコアを試してみてください、それはこの種のタスクで素晴らしいです)

于 2012-05-07T20:50:57.907 に答える