-6

2つの異なるプロバイダーからの2セットの分析データをマージしようとしています。配列、国名、およびメトリックは、次のように配置されます。

[['Albania','1000'],['Australia','1000']]

両方のデータセットに、同じ国名の異なるバージョンを含めることができます(英国ではなく英国など)。これらの配列の配列をJavascriptでマージするにはどうすればよいですか?マージとは、各国のデータセットを単一のアレイセットに結合することを意味します。

例:

[['Albania','1000'],['United Kingdom','1000']]

+

[['Albania','1000'],['UK','1000']]

=

[['Albania','2000'],['United Kingdom','2000']]

明確化:当社のモバイルサイトは1つの分析プロバイダーを使用していますが、メインのグローバルサイトは別の異なる分析プロバイダーを使用しています。正確なレポートを作成するには、これらのデータセットをマージする必要があります。マージする必要のあるデータセットは2つだけです。

4

3 に答える 3

0

これは、PHPの投稿から翻訳された部分的な解決策です。これではエイリアシングは発生しません。PHPの同等のコードは、連想配列があるため、かなりきれいに見えます。配列の代わりにオブジェクトリテラルを使用すると、非常に優れたソリューションを得ることができます。このソリューションでは、プラットフォームに応じてシムが必要になる場合がありArray.indexOfます。Array.concat

http://jsfiddle.net/radu/8JQBS/

var arr1 = [['Albania','1000'],['United Kingdom','1000']],
    arr2 = [['Albania','1000'],['UK','1000']],
    sum = [],
    index = -1;

var mergedArray = arr1.concat(arr2);

for (var i = 0, n = mergedArray.length; i !== n; i++) {

    for (var j = 0, m = sum.length; j !== m; j++) {   
        if (sum[j].indexOf(mergedArray[i][0]) !== -1) {
            index = j;
            break;            
        } else {
            index = -1;
        }
    }

    if (index !== -1) {
        sum[index][1] = (
            parseInt(sum[index][1], 10) +  
            parseInt(mergedArray[i][1], 10)
        ).toString();
    } else {
        sum.push([mergedArray[i][0], mergedArray[i][1]]);
    }
}

これにより、次のようになり[['Albania', '2000'], ['United Kingdom', '1000'], ['UK', '1000']]ます。このためにエイリアシングを実装することもできますが、面倒です。より良い解決策については、以下を参照してください。

結果として配列の配列を生成する代わりに、オブジェクトリテラルを与える別のソリューションがあります。私の意見では、これははるかに優れています。使用しているAPIから取得するデータを制御できない場合がありますが、データの処理方法を制御できます。これにより、ダウンストリームコードが改善されます。これには、のシムが必要になる場合がありますObject.hasOwnProperty

http://jsfiddle.net/radu/fPsdc/

var arr1 = [['Albania','1000'],['United Kingdom','1000']],
    arr2 = [['Albania','1000'],['UK','1000']], 
    mergedArray = arr1.concat(arr2),
    sum = {},

    // property is preferred name
    // define aliases in lowercase
    aliases = {
        'uk' : 'United Kingdom'
    };

for (var i = 0, n = mergedArray.length; i !== n; i++) {
    var country = mergedArray[i][0],
        num = parseInt(mergedArray[i][1], 10);

    if (aliases.hasOwnProperty(country.toLowerCase())) {
        country = aliases[country.toLowerCase()];          
    }

    if (sum.hasOwnProperty(country))
        sum[country] += num;        
    else
        sum[country] = num;
}

これにより、次のようになり{'Albania' : 2000, 'United Kingdom' : 2000}ます。結果として本当に配列の配列が必要な場合は、次のように実行できます。

var arrSum = [];

for (var prop in sum) {
    if (sum.hasOwnProperty(prop)) {
        arrSum.push([prop, sum[prop]]);
    }        
}
于 2012-07-25T15:15:47.743 に答える
0

1つの解決策は、国のすべての可能な名前を単一の値にマップする配列を作成することです。

次に、array_merge()を使用して値を解析し、結果の配列に配置します。

例えば:

<?php
$countryMap = array(
    'United Kingdom'           => 'uk',
    'UK'                       => 'uk',
    'Albania'                  => 'alb'
);

$array1 = array(array('Albania', 1000), array('United Kingdom', 1000));
$array2 = array(array('Albania', 1000), array('UK', 1000));

$mergedArray = array_merge($array1, $array2);

$finalArray = array();

foreach ($mergedArray as $a) {
    if (isset($finalArray[$countryMap[$a[0]]]))
        $finalArray[$countryMap[$a[0]]] += $a[1];
    else
        $finalArray[$countryMap[$a[0]]] = $a[1];
}

var_dump($finalArray);
于 2012-07-25T14:32:20.960 に答える
0

特定の国のすべてのエイリアスを定義する3番目の配列を提供する必要があります。多分次のようなものです:

// the preferred alias is the first element of each set
var countryAliases = [
    [ 'United Kingdom', 'UK' ],
    [ 'United States', 'US'],
    // ...
];

各データ配列をループし、エイリアスマップで各アイテムの国を見つけてから、優先エイリアスをキーとして使用して、結果を単一の結果配列に書き込みます。

于 2012-07-25T14:37:57.950 に答える