0

I'm trying to compute the most used language from a specific GitHub user. Each repository has a list of languages used, and an integer that I assume is the number of characters per each language per repository.

I have systematically fetched every repository that belongs to a user, and then fetched the languages used.

This is not exactly how the GitHub API returns things, I'm just simplifying it to make my issue more apparent.

Assume this array represents all the languages used on all the repositories of a user.

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

I want to iterate over that array to return a new one with the following values, which would represent total language usage on every repository:

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

Since JavaScript was a duplicate, the second usage value 5479 is added to the first and the second object is deleted from the array.

Sounds simple, but I'm having an extremely hard time pulling it off.

What I have tried:

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)
    }
}

What I think this should do is add the language to the array if it doesn't exist, and if it does exist, simply add to the usage that already exists.

My issue is that this implementation never detects that a language already exists in the array. I've been trying to get this working for a few hours and I would really appreciate it if someone told me what I'm missing. I feel like it shouldn't be so hard. Thank you!

2 Answers 2

1

There's plenty of different ways of doing it. Here's one:

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);
Sign up to request clarification or add additional context in comments.

2 Comments

Much appreciated. I'm dipping my toes into declarative programming and JavaScript, and have a better Java background, so it's been hard getting things going. I mention this because it's obvious that I need to learn how to use those array functions.
Of course! I had the same thing when learning these. Practice makes perfect.
1

What I feel, it's pretty straightforward. Let's say you have following array of objects:

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

Now if you know ES6 at least, you probably encounter reduce() so

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

or Simply with for...of loop

    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 
        }
    }

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.