-6

我正在尝试合并来自两个不同提供商的两组分析数据。数组、国家名称和指标排列如下:

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

两个数据集都可以包含相同国家名称的不同版本(例如 UK 而不是 United Kingdom)。如何在 Javascript 中合并这些数组?合并是指将每个国家/地区的数据集组合成一组数组。

例子:

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

+

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

=

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

澄清:我们的移动网站使用一个分析提供商,而我们的主要全球网站使用另一个不同的分析提供商。我们需要合并这些数据集以创建准确的报告。只需要合并 2 个数据集。

4

3 回答 3

0

一种解决方案是创建一个数组,将一个国家的所有可能名称映射到一个值。

然后您可以使用 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

您需要提供第三个数组来定义给定国家/地区的所有别名。也许是这样的:

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

只需遍历每个数据数组,在别名映射中找到每个项目的国家,然后将结果写入单个结果数组,使用首选别名作为键。

于 2012-07-25T14:37:57.950 回答
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 回答