2015-11-22 4 views
1

Я пытаюсь решить следующую проблему в javascript, попробовал различные способы ее реализации, но до настоящего времени не имел реального успеха. У меня есть 2 массивы одинаковой длины, например:Суммируя значения массива, которые соответствуют другому массиву

var years=[2010,2011,2009,2008,2010,2011,2007,2008,2008] 
var money=[2,3,6,5,13,8,3,9,7] 

Индекс каждого элемента money соединен с тем же индексом элемента years с точки зрения какой-то деньги, затраченные в этом году. Я хотел бы, чтобы моя программа построила новый массив разных лет (удаление тех же значений массива years) и новый денежный массив с элементами суммирования начальных значений массива денег, соответствующих каждому году.

years_new=[2010,2011,2009,2008,2007] 
money_new=[2+13,3+8,6,5+9+7,3] 

Как бы я это сделал? Спасибо

ответ

1

Это может быть ответ:

var years=[2010,2011,2009,2008,2010,2011,2007,2008,2008]; 
var money=[2,3,6,5,13,8,3,9,7]; 

fixed_years = Array(); 
for(var i=0; i < years.length; i++){ 
    console.log(fixed_years[years[i]]); 
    if(fixed_years[years[i]]){ 
     fixed_years[years[i]] += money[i]; 
    }else{ 
     fixed_years[years[i]] = money[i]; 
    } 

} 
console.log(fixed_years); 

new_years = Array(); 
new_money = Array(); 
for(year in fixed_years){ 
    new_years.push(year); 
    new_money.push(fixed_years[year]); 
} 
console.log(new_money); 
1

Вы можете использовать временный объект для хранения подсчитанных значений.

var years = [2010, 2011, 2009, 2008, 2010, 2011, 2007, 2008, 2008], 
 
    money = [2, 3, 6, 5, 13, 8, 3, 9, 7], 
 
    count = {}, i = 0, 
 
    years_new = [], 
 
    money_new = []; 
 

 
while (i < years.length && i < money.length) { 
 
    count[years[i]] = (count[years[i]] || 0) + money[i]; 
 
    i++; 
 
} 
 
years_new = Object.keys(count); 
 
money_new = years_new.map(function (a) { return count[a]; }); 
 

 
document.write('<pre>' + JSON.stringify(years_new, 0, 4) + '</pre>'); 
 
document.write('<pre>' + JSON.stringify(money_new, 0, 4) + '</pre>');

Или подсчитывать без временного хранения. Это решение поддерживает порядок исходного массива years.

var years = [2010, 2011, 2009, 2008, 2010, 2011, 2007, 2008, 2008], 
 
    money = [2, 3, 6, 5, 13, 8, 3, 9, 7], 
 
    i = 0, p, 
 
    years_new = [], 
 
    money_new = []; 
 

 
while (i < years.length && i < money.length) { 
 
    p = years_new.indexOf(years[i]); 
 
    if (~p) { 
 
     money_new[p] += money[i]; 
 
    } else { 
 
     years_new.push(years[i]); 
 
     money_new.push(money[i]); 
 
    } 
 
    i++; 
 
} 
 
document.write('<pre>' + JSON.stringify(years_new, 0, 4) + '</pre>'); 
 
document.write('<pre>' + JSON.stringify(money_new, 0, 4) + '</pre>');

Третье предложение, которое снижает как массивы, если индекс years не равен от Array.prototype.indexOf. Затем он объединяет оба массива и добавляет сплайс-значение.

var years = [2010, 2011, 2009, 2008, 2010, 2011, 2007, 2008, 2008], 
 
    money = [2, 3, 6, 5, 13, 8, 3, 9, 7], 
 
    i = years.length, p, 
 
    years_new = years, 
 
    money_new = money; 
 

 
while (i--) { 
 
    p = years_new.indexOf(years_new[i]); 
 
    if (p !== i) { 
 
     years_new.splice(i, 1); 
 
     money_new[p] += +money_new.splice(i, 1); 
 
    } 
 
} 
 
document.write('<pre>' + JSON.stringify(years_new, 0, 4) + '</pre>'); 
 
document.write('<pre>' + JSON.stringify(money_new, 0, 4) + '</pre>');

1

Вы можете создать объект с помощью метода Array.prototype.reduce. Клавиши объекта - годы, а их значение - сумма соответствующих денег элементов массива.

var ret = years.reduce(function(ret, el, i) { 
    ret[el] = (ret[el] || 0) + money[i]; 
    return ret; 
}, {}); 

Для получения всех лет вы можете использовать Object.keys метод:

var years_new = Object.keys(ret); 
var money_new = years_new.map(function(el) { return ret[el] }); 
+0

Обратите внимание на порядок 'years_new' не гарантировано, так что результат может быть перестановкой' [2010,2011,2009,2008,2007] '. Однако 'money_new' будет правильно привязан к этому порядку. – Oriol

+0

@Oriol Да, это совершенно верно. Следует также отметить, что, хотя порядок объектов JavaScript не определен, Chrome/Chromium сортирует объекты, поэтому 'years_new' должен быть отсортированным массивом в этих браузерах. – undefined

1

Вот другой подход, используя следующие хелперы (обратите внимание, что любой другой uniq будет работать, так как это один не предназначен чтобы быть эффективными).

Помощники.

Array.prototype.uniq = function() { 
    return this.reduce(function(sofar, cur) { 
    return sofar.indexOf(cur) < 0 ? sofar.concat([cur]) : sofar; 
    }, []); 
}; 

Array.prototype.indicesOf = function(el) { 
    return this.reduce(function(indices, cur, i) { 
    return (cur === el) ? indices.concat(i) : indices; 
    }, []); 
}; 

Usage.

Теперь задача выбора новых лет является простым вызовом uniq:

var years_new = years.uniq(); 

А карта старого money в требуемому, мы накапливаем старый years и использовать каждый индекс, чтобы получить сумма старого money:

var money_new = years_new.map(function(ny) { 
    return years.indicesOf(ny).reduce(function(sum, index) { 
    return sum + money[index]; 
    }, 0); 
}); 
Смежные вопросы