#javascript #arrays #typescript #merge
#javascript #массивы #typescript #слияние
Вопрос:
Я пытаюсь вычислить наиболее используемый язык от конкретного пользователя GitHub. В каждом репозитории есть список используемых языков и целое число, которое, как я предполагаю, представляет собой количество символов на каждый язык в репозитории.
Я систематически извлекал все репозитории, принадлежащие пользователю, а затем извлекал используемые языки.
Это не совсем то, как API GitHub возвращает вещи, я просто упрощаю это, чтобы сделать мою проблему более очевидной.
Предположим, что этот массив представляет все языки, используемые во всех репозиториях пользователя.
{
"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)
}
}
Я думаю, что это должно сделать, это добавить язык в массив, если он не существует, и если он существует, просто добавьте к использованию, которое уже существует.
Моя проблема в том, что эта реализация никогда не обнаруживает, что язык уже существует в массиве. Я пытался заставить это работать в течение нескольких часов, и я был бы очень признателен, если бы кто-нибудь сказал мне, чего мне не хватает. Я чувствую, что это не должно быть так сложно. Спасибо!
Ответ №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. Очень признателен. Я погружаюсь в декларативное программирование и JavaScript, и у меня лучший опыт работы с Java, поэтому было сложно добиться успеха. Я упоминаю об этом, потому что очевидно, что мне нужно научиться использовать эти функции массива.
2. Конечно! У меня было то же самое при их изучении. Практика совершенствует.
Ответ №2:
Что я чувствую, это довольно просто. Допустим, у вас есть следующий массив объектов:
[
{
"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
}
}