I'm new to js and have a cart in a webstore I am making for a Javascript assignment, and I can't get my total price working which displays on the webpage when the user clicks on items to add to the cart. Here is my array of items, any help would be appreciated, thank you
var cart;
var items = new Array(); //create array to store items
items[0] = "Greatest Hits CD", 10;
items[1] = "Girls CD", 10;
items[2] = "Shirt1", 20;
items[3] = "Mask Tee", 20;
items[4] = "Crewneck", 25;
items[5] = "Tour Poster", 9;
and here is my display function
this.display = function () {
this.holder.innerHTML = "";
this.totalprice = 0;
for (var i=0; i<this.quantities.length; i++) {
if (this.quantities[i] > 0) {
this.totalprice += this.quantities[i]*this.items[i];
var elm = document.createElement('div');
elm.innerHTML = "<span class='name'>"+this.items[i]+" \</span><span class='quantity'>Quantity: "+this.quantities[i]+"</span>";
this.holder.insertBefore(elm, null);
}
}
var elm = document.createElement('div');
elm.innerHTML = "<span class='price'>Total Price: $"+this.totalprice+" </span>";
this.holder.insertBefore(elm, null);
document.getElementById('quantities').value = cart.quantities;
document.getElementById('items').value = cart.items;
}
Array Reduce method is great for that, especially with the combination of Array destruct, since we only care about the price:
var items = [
["Greatest Hits CD", 10],
["Girls CD" , 10],
["Shirt1" , 20],
["Mask Tee" , 20],
["Crewneck" , 25],
["Tour Poster" , 9]
];
console.log(
items.reduce((total, [,price]) => total + price, 0)
);
You are trying to create an associative array (key/value pairs), which isn't how standard arrays work in JavaScript.
Instead, create an array of objects that store the data. Each "record" will be persisted as an object and those objects will each get a common set of property names (prop1 and prop2 in my example). You can then loop through the array of objects and upon each iteration, grab the property you are interested in (prop2) in this case.
var items = new Array(); //create array to store items
// Each item in the array will store an object with 2 properties
// Object literal syntax: {propertyName : propertyValue, propertyName : propertyValue, etc.}
items[0] = {prop1:"Greatest Hits CD", prop2:10};
items[1] = {prop1:"Girls CD", prop2:10};
items[2] = {prop1:"Shirt1", prop2:20};
items[3] = {prop1:"Mask Tee", prop2:20};
items[4] = {prop1:"Crewneck", prop2:25};
items[5] = {prop1:"Tour Poster", prop2:9};
var sum = null; // Place to store the total cost
// The JavaScript Array.prototype specifies a built-in method called
// forEach that takes a function as an argument. That function is
// automatically passed 3 arguments and is executed for each element
// in the array.
items.forEach(function(value, index, arry){
sum += value.prop2;
});
console.log(sum);
Related
I found a lot of answers to similar questions to this, but nothing really hit the nail on the head. I need to know how to remove duplicate objects from an array but before removing them, add some of their attributes to the original object, and I need to do this with regular JavaScript, not jQuery. For example, if I run a fast food restaurant, I want to know how many burgers I sold. Every burger sold is a Food object in an array named burger like this:
burger[i] = new Food(i, name, price, tax);
I don't need to see every single whopper I sold, so I want remove from the array all but one object with a name of whopper burger[i].name but I still want to know the total I sold and tax paid, so I want to add the price and the tax. Now imagine I sell more than just burgers, so my end goal is a table that would list each individual food and it's total price and tax.
Every example I've seen to remove an object from an array seems to remove the object without a chance given to add it's individual attributes to another object first. Thanks in advance, and I apologize if this is confusing or a duplicate, but I swear I've been searching for two hours for an answer for this that works.
#RayfenWindspear #mwilson
Here is the object constructor I'm using:
//object constructor for groups
function customGroup(id, name, count, attend, tax, sold, origID) {
this.ID = id;
this.cNAME = name;
this.cCOUNT = count;
this.cATT = attend;
this.cTAX = tax;
this.cSOLD = sold;
this.cID = origID;
}//Ends function
The code creates two arrays of these objects using this code twice (I'm only putting it once here, the arrays created obviously have different names):
//loop to create objects from all groups in table
for (var i = 0; i < iName.length; i++) {
name = iName[i].innerHTML;
count = parseInt(iCount[i].innerHTML);
//count = Number(count.replace(/[^0-9\.-]+/g,""));
attend = parseInt(iAttend[i].innerHTML);
tax = iTax[i].innerHTML;
tax = Number(tax.replace(/[^0-9\.-]+/g,""));
sold = iSold[i].innerHTML;
sold = Number(sold.replace(/[^0-9\.-]+/g,""));
id = iID[i].innerHTML;
tableNames[i] = new customGroup(i, name, count, attend, tax, sold, id);
}//ends for loop
Then I compare the two tables and make an array of matching objects.
for (var i=0; i < tableNames.length; i++){
for( var j=0; j < otherTableNames.length; j++){
if (tableNames[i].cNAME == otherTableNames[j].cNAME){
count = tableNames[i].cCOUNT + otherTableNames[j].cCOUNT;
attend = tableNames[i].cATT + otherTableNames[j].cATT;
tax = tableNames[i].cTAX + otherTableNames[j].cTAX;
sold = tableNames[i].cSOLD + otherTableNames[j].cSOLD;
temp = new customGroup(j, tableNames[i].cNAME, count, attend, tax, sold, tableNames[i].cID);
namematch.push(temp);
}//ends if statement
}//ends nested loop
}//ends loop
Here is how I was trying to remove items with the same name but keep the original values.
//remove duplicate objects from namematch array
for (var i = 0, len = namematch.length; i < len; i++) {
for (var j = 0, len = namematch.length; j < len2; j++) {
if (namematch[i].cNAME === namematch[j].cNAME) {
if ( i != j){
namematch[i].cCOUNT = namematch[i].cCOUNT + namematch[j].cCOUNT;
namematch[i].cATT = namematch[i].cATT + namematch[j].cATT;
namematch[i].cTAX = namematch[i].cTAX + namematch[j].cTAX;
namematch[i].cSOLD = namematch[i].cSOLD + namematch[j].cSOLD;
namematch.splice(j, 1);
len2=namematch.length;
}//ends if statement
}//endsif statement
}//ends Nested loop
}//ends forloop
What you might want to do is, to take your burger array, .filter(fn) for burgers with the same name, and then .reduce(fn) to just a single entry.
You could use an object for grouping the single values and if necessary, you could render a single array out of it.
function Food(i, name, price, tax) {
this.i = i;
this.name = name;
this.price = price;
this.tax = tax;
}
var burger = [
new Food(0, 'Hamburger', 2, 0.4),
new Food(1, 'Cheeseburger', 2.5, 0.5),
new Food(2, 'Hamburger', 2, 0.4),
new Food(3, 'Cheeseburger', 2.5, 0.5),
new Food(4, 'Hamburger', 2, 0.4),
new Food(5, 'Cheeseburger', 2.5, 0.5),
new Food(6, 'Cheeseburger', 2.5, 0.5),
new Food(7, 'Hamburger', 2, 0.4),
],
grouped = Object.create(null),
result;
burger.forEach(function (food) {
grouped[food.name] = grouped[food.name] || { name: food.name, count: 0, price: 0, tax: 0 };
grouped[food.name].count++;
grouped[food.name].price += food.price;
grouped[food.name].tax += food.tax;
});
result = Object.keys(grouped).map(function (k) { return grouped[k]; });
console.log(grouped);
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Use a Map to hold unique items and iterate the array with a for loop. Add items if they are not in the map, if already in the map add the data you want to the existing item. When done convert the maps values back to an array.
var items = [
{ type : "food1",sold : 2},
{ type : "food3",sold : 1},
{ type : "food2",sold : 3},
{ type : "food1",sold : 5},
{ type : "food3",sold : 1},
{ type : "food2",sold : 3},
{ type : "food1",sold : 5},
]
// reduce the array into a Map
var reduced = new Map();
items.forEach(item=>{ // for each item
var red = reduced.get(item.type); // get the mapped item by the item type
if(red !== undefined){ // is it defined
red.sold += item.sold; // yes add to the total
}else{
reduced.set(item.type,item); // no then add to the map
}
})
items.length = 0; // empty the old array
items.push(...reduced.values()); // add the reduced items
console.log(items); // show result
I wanted to know if its possible to ad elements to an array which is declared as the following...
Please check the add() function, I can't figure out how to solve this problem. Thanks
It's not necessary, but I'd appreciate if you give an explanation since of c++ point of view programmer.
// My array is this way declared
var myArray = [
['John', 'Doe', '1980'],
['Jane','Malloy','1982'],
['Vincent','Malloy','1972']
];
// then I want to add a new elements in it, but It seems to doesn't work
var add = function() {
//var textbox = document.getElementById('textbox').value;
// storing new person in array
myArray [3][0] = 'New1';
myArray [3][1] = 'New2';
myArray [3][2] = 'New3';
};
//finally this function is for displaying the elements of myArray
var show = function() {
// clean output
document.getElementById('output').innerHTML = '';
// delay time
setTimeout (function() {
// showing info. people
for (var i in myArray) {
for (var j in myArray)
document.getElementById('output').innerHTML += myArray[i][j] + ' ';
document.getElementById('output').innerHTML += '<br/>';
}
}, 250);
};
So right here:
var add = function() {
//var textbox = document.getElementById('textbox').value;
// storing new person in array
myArray [3][0] = 'New1';
myArray [3][1] = 'New2';
myArray [3][2] = 'New3';
};
You can't add to myArray[3] because myArray[3] is undefined. You need to assign an empty array to myArray[3] first:
myArray [3] = [];
myArray [3][0] = 'New1';
myArray [3][1] = 'New2';
myArray [3][2] = 'New3';
Or more generally, assuming the idea is to add to the end of your array, you could do something like:
var idx = myArray.length;
myArray[idx] = [];
myArray[idx][0] = "New 1";
// ...
Or even something like:
var newArray = ["New1", "New2", "New3"];
myArray.push(newArray);
I have two arrays which are
product_id = [5,5,10,15,5,15,22]
product_qty = [58,40,120,100,98,100,50]
(I have stored to array as sequence from table. id and quantity orders are same as i mentioned above.)
I want to calculate the same id's total quantity with their id. Result should be
result_id = [5,10,15,22] //no duplicates
result_qty = [196,120,200,50] //sum to same id's quantity
how to solve this issue in javascript?
One possible solution (keeping the two array solution as specified in the question, although you may want to look into a hash as specified by Vineswaran in the comments) is to traverse the first array (with the ids) and push the value if it doesn't exist in the index array, or add the value if it exists in the index array, like this:
var product_id = [5,5,10,15,5,15,22];
var product_qty = [58,40,120,100,98,100,50];
var result_id = [];
var result_qty = [];
// traverse the product ids array
$.each(product_id, function(idx, val) {
// check if that product id had a previous instance
var auxIdx = $.inArray(val, result_id)
if (auxIdx >= 0) {
// if it did, add the quantities
result_qty[auxIdx] += product_qty[idx];
} else {
// if it didn't, push both id and quantity into the result arrays
result_id.push(val);
result_qty.push(product_qty[idx]);
}
});
console.log(result_id);
console.log(result_qty);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
You can see it on this JSFiddle too: http://jsfiddle.net/pmkLcLdd/
I don't have your sample data. So, i have modified your code in the comment.
var store_product = {};
$(data).each(function(did,value){
var product_place_id = value.product_place_id_primary;
var ids = getProductAndPlaceId(product_place_id);
var item_quantity = store_product[ids[0]];
if (item_quantity) {
store_product[ids[0]] = (item_quantity + value.quantity);
} else {
store_product[ids[0]] = value.quantity;
}
});
store_product hash will have your expected result. You can convert it into array or anything as per your needs.
you don't need jquery for this
var product_id = [5,5,10,15,5,15,22]
var product_qty = [58,40,120,100,98,100,50]
var result_id = product_id.slice(); //Copy arrays
var result_qty = product_qty.slice()
var i = result_id.length;
while(i > 0){
var id = result_id.shift(); //remove first element
--i;
var sum = result_qty.shift(); //init sum count
var index = result_id.indexOf(id, 0); //find next match of element
while(index != -1){
result_id.splice(index, 1); //remove element in index
--i;
sum += result_qty.splice(index, 1)[0]; //index 0, since splice return a list with length 1
index = result_id.indexOf(id,index);
}
result_id.push(id); //add to end
result_qty.push(sum);
}
console.log(result_id);
console.log(result_qty);
<script src="http://gh-canon.github.io/stack-snippet-console/console.min.js"></script>
I think an object would be better suited for what you want as a result, this way, you can easily relate an id to its quantity, with the id being the key:
var product_id = [5,5,10,15,5,15,22],
product_qty = [58,40,120,100,98,100,50],
result_qty = {};
product_qty.forEach(function (qty, i) {
var indexVal = result_qty[product_id[i]] || 0;
result_qty[product_id[i]] = indexVal + qty;
});
console.log(result_qty);
// Logs Object {5: 196, 10: 120, 15: 200, 22: 50}
console.log(result_qty[5]);
// Logs 196
//////////////////////////////////////////////////////////////////
// * However, if you really want both, the ids and quantities in
// * array format, then it's just a matter of running this,
// * after the previous code:
var tmp = [],
result_id = [];
// * (looping through the object)
for(var prop in result_qty) {
if(result_qty.hasOwnProperty(prop)) {
tmp.push(result_qty[prop]);
result_id.push(parseInt(prop, 10));
}
}
result_qty = tmp;
console.log(result_id);
// Logs [196, 120, 200, 50]
console.log(result_qty);
// Logs [5, 10, 15, 22]
I've included a way to get the arrays anyway, so you have both options.
I have a question about array as below
array = {}
and
array = [];
its same or not?.
also wish to ask
array { ID1 : "apple", ID2 : "Orange"}
and
array [ID1 : "apple", ID2 : "Orange"];
which is correct?.
now i coding my code with below and need your help to teach me about ARRAY.
var Store = [ store = 0, store1 = 0, store2 = 0,store3 = 0,store4 = 0];
var stock1 = 77,stock2 = 47,stock3 = 37,stock4 = 27,stock5 = 17;
for(i=0;i<stock1;i++){
store[0]++
}
var Sum_1 = Store;
document.getElementById('show1').innerHTML=Sum_1;
output will be
77
my question is how to i output it become
store = 77
store1 = 47
store2 = 37
Most with ID or Name together and value.
Thank you so much.
[] are used for a literal Array declaration, {} for a literal Object declaration.
Arrays are initialized without a value by using:
var my_array = [];
and with values:
var my_array = [1, 2, 3];
Note that you cannot set the index by this. You would have to do:
var my_array = [];
my_array["one"] = 1;
// etc.
You can then get "1" back by my_array["one"]
If you want to get the actual index name or "key" then you will need to do some trickery:
var outputString = "";
function ListAll()
{
for(var key in my_array)
{
if(my_array.hasOwnProperty(key)) // Check if the key is actually a property (index)
{
outputString += key + " = " + my_array[key]; // add to string
}
}
alert(outputString); // or assign the string to a div, whatever you need
}
in this example, key would be the index and my_array[key] the actual value
I have an array of items as follows in Javascript:
var users = Array();
users[562] = 'testuser3';
users[16] = 'testuser6';
users[834] = 'testuser1';
users[823] = 'testuser4';
users[23] = 'testuser2';
users[917] = 'testuser5';
I need to sort that array to get the following output:
users[834] = 'testuser1';
users[23] = 'testuser2';
users[562] = 'testuser3';
users[823] = 'testuser4';
users[917] = 'testuser5';
users[16] = 'testuser6';
Notice how it is sorted by the value of the array and the value-to-index association is maintained after the array is sorted (that is critical). I have looked for a solution to this, tried making it, but have hit a wall.
By the way, I am aware that this is technically not an array since that would mean the indices are always iterating 0 through n where n+1 is the counting number proceeding n. However you define it, the requirement for the project is still the same. Also, if it makes a difference, I am NOT using jquery.
The order of the elements of an array is defined by the index. So even if you specify the values in a different order, the values will always be stored in the order of their indices and undefined indices are undefined:
> var arr = [];
> arr[2] = 2;
> arr[0] = 0;
> arr
[0, undefined, 2]
Now if you want to store the pair of index and value, you will need a different data structure, maybe an array of array like this:
var arr = [
[562, 'testuser3'],
[16, 'testuser6'],
[834, 'testuser1'],
[823, 'testuser4'],
[23, 'testuser2'],
[917, 'testuser5']
];
This can be sorted with this comparison function:
function cmp(a, b) {
return a[1].localeCompare(b[1]);
}
arr.sort(cmp);
The result is this array:
[
[834, 'testuser1'],
[23, 'testuser2'],
[562, 'testuser3'],
[823, 'testuser4'],
[917, 'testuser5'],
[16, 'testuser6']
]
If I understand the question correctly, you're using arrays in a way they are not intended to be used. In fact, the initialization style
// Don't do this!
var array = new Array();
array[0] = 'value';
array[1] = 'value';
array[2] = 'value';
teaches wrong things about the nature and purpose of arrays. An array is an ordered list of items, indexed from zero up. The right way to create an array is with an array literal:
var array = [
'value',
'value',
'value'
]
The indexes are implied based on the order the items are specified. Creating an array and setting users[562] = 'testuser3' implies that there are at least 562 other users in the list, and that you have a reason for only knowing the 563rd at this time.
In your case, the index is data, and is does not represent the order of the items in the set. What you're looking for is a map or dictionary, represented in JavaScript by a plain object:
var users = {
562: 'testuser3',
16: 'testuser6',
834: 'testuser1',
823: 'testuser4',
23: 'testuser2',
917: 'testuser5'
}
Now your set does not have an order, but does have meaningful keys. From here, you can follow galambalazs's advice to create an array of the object's keys:
var userOrder;
if (typeof Object.keys === 'function') {
userOrder = Object.keys(users);
} else {
for (var key in users) {
userOrder.push(key);
}
}
…then sort it:
userOrder.sort(function(a, b){
return users[a].localeCompare(users[b]);
});
Here's a demo
You can't order arrays like this in Javascript. Your best bet is to make a map for order.
order = new Array();
order[0] = 562;
order[1] = 16;
order[2] = 834;
order[3] = 823;
order[4] = 23;
order[5] = 917;
In this way, you can have any order you want independently of the keys in the original array.
To sort your array use a custom sorting function.
order.sort( function(a, b) {
if ( users[a] < users[b] ) return -1;
else if ( users[a] > users[b] ) return 1;
else return 0;
});
for ( var i = 0; i < order.length; i++ ) {
// users[ order[i] ]
}
[Demo]
Using the ideas from the comments, I came up with the following solution. The naturalSort function is something I found on google and I modified it to sort a multidimensional array. Basically, I made the users array a multidimensional array with the first index being the user id and the second index being the user name. So:
users[0][0] = 72;
users[0][1] = 'testuser4';
users[1][0] = 91;
users[1][1] = 'testuser2';
users[2][0] = 12;
users[2][1] = 'testuser8';
users[3][0] = 3;
users[3][1] = 'testuser1';
users[4][0] = 18;
users[4][1] = 'testuser7';
users[5][0] = 47;
users[5][1] = 'testuser3';
users[6][0] = 16;
users[6][1] = 'testuser6';
users[7][0] = 20;
users[7][1] = 'testuser5';
I then sorted the array to get the following output:
users_sorted[0][0] = 3;
users_sorted[0][1] = 'testuser1';
users_sorted[1][0] = 91;
users_sorted[1][1] = 'testuser2';
users_sorted[2][0] = 47;
users_sorted[2][1] = 'testuser3';
users_sorted[3][0] = 72;
users_sorted[3][1] = 'testuser4';
users_sorted[4][0] = 20;
users_sorted[4][1] = 'testuser5';
users_sorted[5][0] = 16;
users_sorted[5][1] = 'testuser6';
users_sorted[6][0] = 18;
users_sorted[6][1] = 'testuser7';
users_sorted[7][0] = 12;
users_sorted[7][1] = 'testuser8';
The code to do this is below:
function naturalSort(a, b) // Function to natural-case insensitive sort multidimensional arrays by second index
{
// setup temp-scope variables for comparison evauluation
var re = /(-?[0-9\.]+)/g,
x = a[1].toString().toLowerCase() || '',
y = b[1].toString().toLowerCase() || '',
nC = String.fromCharCode(0),
xN = x.replace( re, nC + '$1' + nC ).split(nC),
yN = y.replace( re, nC + '$1' + nC ).split(nC),
xD = (new Date(x)).getTime(),
yD = xD ? (new Date(y)).getTime() : null;
// natural sorting of dates
if ( yD )
if ( xD < yD ) return -1;
else if ( xD > yD ) return 1;
// natural sorting through split numeric strings and default strings
for( var cLoc = 0, numS = Math.max(xN.length, yN.length); cLoc < numS; cLoc++ ) {
oFxNcL = parseFloat(xN[cLoc]) || xN[cLoc];
oFyNcL = parseFloat(yN[cLoc]) || yN[cLoc];
if (oFxNcL < oFyNcL) return -1;
else if (oFxNcL > oFyNcL) return 1;
}
return 0;
}
// Set values for index
var users = Array();
var temp = Array();
users.push(Array('72', 'testuser4'));
users.push(Array('91', 'testuser2'));
users.push(Array('12', 'testuser8'));
users.push(Array('3', 'testuser1'));
users.push(Array('18', 'testuser7'));
users.push(Array('47', 'testuser3'));
users.push(Array('16', 'testuser6'));
users.push(Array('20', 'testuser5'));
// Sort the array
var users_sorted = Array();
users_sorted = users.sort(naturalSort);
I'd use map once to make a new array of users,
then a second time to return the string you want from the new array.
var users= [];
users[562]= 'testuser3';
users[16]= 'testuser6';
users[834]= 'testuser1';
users[823]= 'testuser4';
users[23]= 'testuser2';
users[917]= 'testuser5';
var u2= [];
users.map(function(itm, i){
if(itm){
var n= parseInt(itm.substring(8), 10);
u2[n]= i;
}
});
u2.map(function(itm, i){
return 'users['+itm+']= testuser'+i;
}).join('\n');
/*returned value: (String)
users[834]= testuser1
users[23]= testuser2
users[562]= testuser3
users[823]= testuser4
users[917]= testuser5
users[16]= testuser6
*/
If you want to avoid any gaps. use a simple filter on the output-
u2.map(function(itm, i){
return 'users['+itm+']= testuser'+i;
}).filter(function(itm){return itm}).join('\n');
Sparse arrays usually spell trouble. You're better off saving key-value pairs in an array as objects (this technique is also valid JSON):
users = [{
"562": "testuser3"
},{
"16": "testuser6"
}, {
"834": "testuser1"
}, {
"823": "testuser4"
}, {
"23": "testuser2"
}, {
"917": "testuser5"
}];
As suggested, you can use a for loop to map the sorting function onto the array.
Array.prototype.sort() takes an optional custom comparison function -- so if you dump all of your users into an array in this manner [ [562, "testuser3"], [16, "testuser6"] ... etc.]
Then sort this array with the following function:
function(comparatorA, comparatorB) {
var userA = comparatorA[1], userB = comparatorB[1]
if (userA > userB) return 1;
if (userA < userB) return -1;
if (userA === userB) return 0;
}
Then rebuild your users object. (Which will loose you your sorting.) Or, keep the data in the newly sorted array of arrays, if that will work for your application.
A oneliner with array of array as a result:
For sorting by Key.
let usersMap = users.map((item, i) => [i, item]).sort((a, b) => a[0] - b[0]);
For sorting by Value. (works with primitive types)
let usersMap = users.map((item, i) => [i, item]).sort((a, b) => a[1] - b[1]);