Title: JQuery add another value to each array item & sum
Tags: javascript;jquery;arrays
Question: I currently have an array that is populated by changing the value/option of many select fields. E.g. If two select fields are in the dom and the options selected are 2 &amp; 3 then the array would look like this - Array [ "2", "3" ]
Each select has a data attribute data-ticketprice which I would like to bind to each of the option values. So I can get the sum of both of the numbers e.g.
data attribute = 100
Select option value = 5
Sum = 100 x 5;
HTML -
<select class="ticket-qty" data-ticketprice="280.88" name="34"&gt;
<option value="0"&gt;0 Tickets</option&gt;
<option value="1"&gt;1 Ticket</option&gt;
<option value="2"&gt;2 Tickets</option&gt;
<option value="3"&gt;3 Tickets</option&gt;
<option value="4"&gt;4 Tickets</option&gt;
<option value="5"&gt;5 Tickets</option&gt;
</select&gt;
<select class="ticket-qty" data-ticketprice="390" name="39"&gt;
<option value="0"&gt;0 Tickets</option&gt;
<option value="1"&gt;1 Ticket</option&gt;
<option value="2"&gt;2 Tickets</option&gt;
<option value="3"&gt;3 Tickets</option&gt;
<option value="4"&gt;4 Tickets</option&gt;
<option value="5"&gt;5 Tickets</option&gt;
</select&gt;
Current jQuery -
//When select is changed update value to array
$('select.ticket-qty').on('change', function (e) {
//Map the values for the array
var arr = $('select.ticket-qty').map(function(){
return this.value
}).get()
//This sums the all the select options (not what I want)
var total = 0;
for (var i = 0; i < arr.length; i++) {
total += arr[i] << 0;
console.log(total);
Comment: @AdamLeggett  I'm already using an MVC framework such as Laravel. I don't like VueJS because you end up with around 100 libraries. It's never just vue, its axios, vue routing etc.. This is a really basic application with almost no JS requirements.

Comment: You don't need a big framework for every little problem.

Comment: Please consider using an MVC framework for this type of project. Vue JS is easy to get started with if you haven't done so before.

Comment: If this is a school project, probably not. If he is really selling tickets to something, this will outgrow jQuery within a day.

Here is the accepted answer: You need to fill the array you build with map() with the selected quantity multiplied by the cost per item, which you can retrieve from the data attribute. From there you can use reduce() to sum up all values in the array. Something like this:
$('select.ticket-qty').on('change', function(e) {
var arr = $('select.ticket-qty').map(function() {
var cost = $(this).data('ticketprice');
var qty = $(this).val();
return cost * qty;
}).get();
var total = arr.reduce((a, b) =&gt; a + b, 0);
console.log(total);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"&gt;</script&gt;
<select class="ticket-qty" data-ticketprice="280.88" name="34"&gt;
<option value="0"&gt;0 Tickets</option&gt;
<option value="1"&gt;1 Ticket</option&gt;
<option value="2"&gt;2 Tickets</option&gt;
<option value="3"&gt;3 Tickets</option&gt;
<option value="4"&gt;4 Tickets</option&gt;
<option value="5"&gt;5 Tickets</option&gt;
</select&gt;
<select class="ticket-qty" data-ticketprice="390" name="39"&gt;
<option value="0"&gt;0 Tickets</option&gt;
<option value="1"&gt;1 Ticket</option&gt;
<option value="2"&gt;2 Tickets</option&gt;
<option value="3"&gt;3 Tickets</option&gt;
<option value="4"&gt;4 Tickets</option&gt;
<option value="5"&gt;5 Tickets</option&gt;
</select&gt;
You should note that this can all be done in a single loop, however I am assuming you're building the array of individual totals for use elsewhere in your UI.
Comment for this answer: So this provides the total sum which is great! Would it be possible to have the sub total so the total of each option * data attr
Comment for this answer: @AdamLeggett: IE9 supports most of ECMAScript 5, including `.reduce()`.
Comment for this answer: Unfortunately so. We can dream of a world without IE and Edge... one day.
Comment for this answer: It's better than IE admittedly, but it's still a long way from where it should be. It's standards compliance is rather lacking. It'll be the new IE6 in 3-4 years time.
Comment for this answer: @doodlemeister good point, it's IE8 and lower that'll need to polyfill. I'll didn't bother to check it if I'm honest. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce#Browser_compatibility
Comment for this answer: You can use a `for` loop, as you already do in your question, or even a `forEach`
Comment for this answer: He will need a polyfill for reduce if he wishes to support IE9.
Comment for this answer: Edge isn't that bad.
Comment for this answer: @doodlemeister - my bad, you are correct. I don't think anyone needs to support IE8 at this point, so he is good.

Here is another answer: You can use some jQuery plugins to populate and reduce the select boxes.
(function($) {
$.reduce = function(arr, fn, initial) {
initial = typeof initial === 'undefined' ? 0 : initial;
$.each(arr, function(i, v) {
initial = fn(initial, v, i);
});
return initial;
$.fn.reduce = function(fn, initial) {
return $.reduce(this, fn, initial);
$.fn.populateCombo = function(opts) {
let data = opts.data || Array.apply(null, {length: opts.range || 0}).map(Number.call, Number);
return this.append(data.map(x =&gt; $('<option&gt;')
.text(opts.textFn ? opts.textFn(x) : x)
.val(opts.valFn ? opts.valFn(x) : x)));
})(jQuery);
$('.ticket-qty').each((i, combo) =&gt; $(combo).populateCombo({
range : 6, textFn: v =&gt; v + ' Tickets'
$('select.ticket-qty').on('change', function(e) {
var total = $('select.ticket-qty').reduce(function(result, item) {
return result + $(item).data('ticketprice') * $(item).val();
}, 0);
console.log('$' + total.toFixed(2));
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"&gt;</script&gt;
<select class="ticket-qty" data-ticketprice="280.88" name="34"&gt;</select&gt;
<select class="ticket-qty" data-ticketprice="390" name="39"&gt;</select&gt;

Here is another answer: So how far I understand is, you want to multiply the selected value with the given data attribute on Select?
Here is sample code for getting Array of All selected values. And how to calculate the value you posted.
var array = [];
var i =0;
$('select.ticket-qty').on('change', function (e) {
// Get value of all selects in array.
$('select.ticket-qty').each(function(){
array[i] = $(this).val();
i++;
});
//calculate Sum ?
var data_attribute = $(this).data("ticketprice");
SelectedOptionValue = = $(this).val();
Sum = parseFloat(data_attribute)* parseInt(SelectedOptionValue);

Here is another answer: Vanilla JS
const SELECTS = document.querySelectorAll('select.ticket-qty')
const LOG_SUM = e =&gt; {
const ticketPrice = e.target.getAttribute('data-ticketPrice')
const multiplier = e.target.value
const SUM = (+ticketPrice * +multiplier)
console.log(SUM)
SELECTS.forEach(select =&gt; {
select.addEventListener('change', e =&gt; {
LOG_SUM(e)
jQuery
$('select.ticket-qty').on('change', e =&gt; {
const ticketPrice = $(e.target).attr('data-ticketPrice')
const multiplier = e.target.value
const SUM = (+ticketPrice * +multiplier)
console.log(SUM)
Notice how i prepend the + operator to the ticketPrice &amp; multiplier constants... this is because attr &amp;&amp; value are returning Strings and the + operator converts numbers of type String into numbers of type Number

{'source': 'StackExchangeDataset', 'subset': 'stackoverflow.com', 'metadata': {'AnswerCount': 4, 'CommentCount': 4, 'ContentLicense': 'CC BY-SA 3.0', 'CreationDate': '2018:00:02/21/18', 'FavoriteCount': 1.0, 'PostTypeId': 1, 'Tags': '<javascript><jquery><arrays>', 'Title': 'JQuery add another value to each array item & sum', 'ViewCount': 101, 'id': 48910691, 'user_AboutMe': '', 'user_AccountId': 1938066.0, 'user_DisplayName': 'archvist', 'user_Reputation': 712.0, 'user_Views': 180.0, 'user_id': 1745014.0}}