如果多个对象对特定键具有相同的值,则合并数组中的特定对象

时间:2021-03-31 20:27:18

标签: javascript arrays typescript merge

我正在尝试计算特定 GitHub 用户最常用的语言。每个存储库都有一个使用的语言列表,我假设一个整数是每个存储库每种语言的字符数。

我已经系统地获取了属于用户的每个存储库,然后获取了使用的语言。

这并不是 GitHub API 返回内容的确切方式,我只是对其进行了简化以使我的问题更加明显。

假设这个数组代表用户的所有存储库上使用的所有语言。

{
    "language": "JavaScript",
    "usage": 102378
},
{
    "language": "PHP",
    "usage": 6031
},
{
    "language": "JavaScript",
    "usage": 5479
}

我想遍历该数组以返回一个具有以下值的新数组,这将代表每个存储库上的总语言使用情况:

{
    "language": "JavaScript",
    "usage": 107857
},
{
    "language": "PHP",
    "usage": 6031
}

由于 JavaScript 是重复的,因此第二个使用值 5479 被添加到第一个,并从数组中删除第二个对象。

听起来很简单,但我很难做到。

我尝试过的:

let languageList = [
    {
        language: 'JavaScript',
        usage: 102379
    },
    {
        language: 'PHP',
        usage: 6031
    }
]


let language = {
    language: 'JavaScript',
    usage: 5479
}

// If array is empty, add the language object.
if(languageList.length === 0) {
    languageList.push(language)
} else {
    // boolean keeps track of existence of language in languageList
    let exists = false
    // For every language in language list...
    for(let x = 0; x < languageList; x++) {
        // Compare the language string and if they match...
        if(languageList[x].language === language.language) {
            // Add the usage number to the existing object in languageList
            languageList[x].usage += language.usage
            exists = true
        }
    }
    // If, after going through all array objects, it wasn't found, add language to list.
    if(!exists) {
        languageList.push(language)
    }
}

我认为这应该做的是将语言添加到数组中,如果它不存在,如果它存在,只需添加到已经存在的用法中。

我的问题是这个实现从来没有检测到数组中已经存在一种语言。我一直在努力让它工作几个小时,如果有人告诉我我错过了什么,我将不胜感激。我觉得应该没那么难。谢谢!

2 个答案:

答案 0 :(得分:1)

有很多不同的方法可以做到这一点。这是一个:

let list = [{
    "language": "JavaScript",
    "usage": 102378
},
{
    "language": "PHP",
    "usage": 6031
},
{
    "language": "JavaScript",
    "usage": 5479
}]

// convert the list to just an array of the language types
let result = list.map(({ language }) => language)
    // remove any duplicates
    .filter((language, index, array) => array.indexOf(language) === index)
    .map(language => ({
        language,
        // sum up the values where the language matches
        usage: list.filter(entry => entry.language === language)
            .reduce((accum, { usage }) => accum + usage, 0)
    }));
    
console.log(result);

答案 1 :(得分:1)

我的感觉,很简单。假设您有以下对象数组:

[
    {
        "language": "JavaScript",
        "usage": 102378
    },
    {
        "language": "PHP",
        "usage": 6031
    },
    {
        "language": "JavaScript",
        "usage": 5479
    }
]

现在如果你至少了解 ES6,你可能会遇到 reduce() 所以

    let res = langaues.reduce((agg, curr) => {
        return {
            ...agg,
            [curr.language]: agg[curr.language] ? agg[curr.language] + curr.usage : curr.usage
        }
    } , {})

或简单地使用 for...of 循环

    let res = {};

    for(let curr of languages) {
        res = {
            ...res // previous store key/value pairs,
            [curr.language]: res[curr.language] ? res[curr.language] + curr.usage : curr.usage 
        }
    }