Cannot reduce array inside of an object - javascript

I am trying to reduce an array inside of an object. I am getting back
push is not a function
I have started my array as empty and created a add function to pass in as the first argument.
function add(a,b) {
return a +b;
}
var navBarArray = [];
var listArray = [];
var mapping = {
".navbar": navBarArray,
".list-group": listArray
};
I tried this approach on the mapping object but it creates errors
var mapping = {
".navbar": Math.round(navBarArray.reduce(add,0) ),
".list-group": listArray
};
However, I get push is not a function back in my console.
Below is my function that passes values to the array. I can create a variable inside the function and reduce it there. However, that limits access to my variable and will bloat my function as I continue.
Object.keys(mapping).forEach(function(selector) {
$(selector).hover(function(evt) {
console.log('mapping',mapping);
console.log('selector',selector);
enteredTime = new Date();
}, function() {
var ctime = new Date();
var time = (ctime.getTime() - enteredTime.getTime())/1000;
mapping[selector].push(time);
// *********** this works but not where I need it to*******
var reduce = Math.round(navBarArray.reduce(add,0) );
console.log(reduce);
});
})

Change your mapping object so it has separate places for the array and total:
var mapping = {
".navbar": {
total: 0,
times: []
},
".list-group": {
total: 0,
times: []
}
}
Then you do mapping[selector].times.push(time), and put the total with:
mapping[selector].total = mapping[selector].times.reduce(add, 0);

Related

How to remove/delete a game object

How do you make an object that can kill/remove itself? e.g.
var bullet = [];
function bullet() {
this.removeSelf = () => {
this = false;
}
}
function setup() {
bullet[0] = new Bullet();
bullet[0].removeSelf();
}
setup(); 
Not sure if I understood your question correctly but if you mean to destroy the object and free the memory then you first need to remove all references to it and then garbage collector will automatically do the job for you.
You're storing a reference to the object in the array so you can do this:
bullet[0] = null
If the goal is to remove it from the parent array, you need to edit that array. So we can pass the parent into the instance and have the removeSelf look for its instance in the parent and splice it out.
I also renamed the constructor to Bullet.
var bullets = [];
function Bullet(parent) {
this.removeSelf = () => {
const index = parent.indexOf(this);
parent.splice(index, 1);
}
}
function setup() {
bullets[0] = new Bullet(bullets);
bullets[1] = new Bullet(bullets); // Add a second isntance to the array
bullets[0].removeSelf();
}
setup(); 
console.log(bullets.length) // Should be 1

Array format showing as object

hope you are doing well. I have faced an issue. I'm creating a dynamic array but when I console that variable and check typeOf of this variable it showing an object instead of an array. Also when I access a specific element of that variable it's showing undefined. Let me know how can I resolve this issue. you can check I have declared a global variable name of test and push data in it. it should return an array because I'm pushing it in the array. But showing object.
$(document).ready(async function(){
await load_pre_data(true);
});
let pre_data= [];
let count = 1;
var test = [];
let ws = new WebSocket('wss://ws.binaryws.com/websockets/v3?app_id=1089');
async function load_pre_data() {
ws.onopen = function (evt) {
ws.send(JSON.stringify({
ticks_history: 'frxAUDJPY',
adjust_start_time: 1,
count: 5,
end: "latest",
start: 1,
style: "ticks"
}));
};
ws.onmessage = function (msg) {
let response = JSON.parse(msg.data);
let loop;
for (loop = 0; loop <= response.history.prices.length; loop++) {
test.push(1);
}
}
console.log(test);
console.log(typeof (test));
}
In Javascript every array is the type of an object and for your typechecking you can use "Array.isArray(test)".
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/isArray
You can read about isArray() method here

Change value of dynamically added js object

I have an array with some predefined data
var data = [
{amount:20, speed:100},
{amount:40, speed:50}
];
I am then adding data to the above array
function addMore() {
data = appendObjTo(data, {amount: 1500,speed:100});
}
function appendObjTo(thatArray, newObj) {
const frozenObj = Object.freeze(newObj);
return Object.freeze(thatArray.concat(frozenObj));
}
The data is being added fine, but for some reason, i am unable to change the value of the new data
function runData() {
perSec = 0;
$.each(data, function( key, value ) {
perSecCalc = Math.round(value.speed/60);
perSec += perSecCalc;
// Below line works only for predefined objects, but not objects from "addMore()"
data[key].amount = value.amount-perSec;
});
setTimeout(function() {
runData();
},1000);
}
While the predefined object in "var data" is being changed, the dynamically added data from "addMore" does not change.
How come the new data is not changing ?
Update:
See this fiddle
You are using Object.freeze in your appendObjTo function. The definition of Object.freeze - Object.freeze().
Since the frozenObj is created using Object.freeze(), the values are not allowed to change. Also, you are not getting any error on console. JS doesn't show error w/o strict mode enabled. I have modified the fiddle to include strict mode, and you can see that it throws and error when you do data[key].amount = value.amount-perSec;. I have also attached a fiddle to play with the Object.freeze() method, and you can experiment by yourself.
Modified fiddle
JS
(function () {
"use strict";
var data = [
{amount:20, speed:100}
];
function runData() {
var perSec = 0;
$.each(data, function( key, value ) {
var perSecCalc = Math.round(value.speed/60);
perSec += perSecCalc;
// Below line works only for predefined objects, but not objects from "addMore()"
data[key].amount = value.amount-perSec;
$('#test').prepend(data[key].amount+'<br>');
});
setTimeout(function() {
runData();
},1000);
}
function appendObjTo(thatArray, newObj) {
const frozenObj = Object.freeze(newObj);
return Object.freeze(thatArray.concat(frozenObj));
}
function addMore() {
data = appendObjTo(data, {amount: 1500,speed:100});
}
setTimeout(function() { addMore(); },1500);
runData();
})();
Object.freeze fiddle
var arr = [10, 20, 30];
console.log(arr);
arr = Object.freeze(arr.concat([40, 50]));
console.log(arr);
arr[3] = 80;
console.log(arr); // doesn't change
// arr.push(60); // error, cannot add property 5, object is not extensible
arr = Object.freeze(arr.concat([{ x: 100 }]));
console.log(arr);
arr[5].x = 200;
console.log(arr); // changes, as Object.freeze only locks the first level values.

Create One Array of Objects

I have the following code which is triggered using JQuery.UI.Sortable and it is behaving unexpectedly.
I need to create one array of objects in this function and return it every time it is called.
function saveOrder(el) {
var slideOrder = new Array();
$(el).each(function() {
var slideId = $(this).attr("data-llp-slide-id"),
slideNo = $(this).attr("data-llp-slide-number"),
slideOb = {slideId,slideNo};
slideOrder.push(slideOb);
});
return slideOrder;
}
What I am getting is multiple objects/arrays returned
Code that is triggering the function above as requested by #Rhumborl
function init() {
$('.slide-list').sortable({
connectWith: ".connected-sortable",
stack: '.connected-sortable ul',
stop: function(e){
$(".slide-item").each(function(i, el){
var hash = $(el).index()+1;
$(el).attr('data-llp-slide-number',hash);
$(el).find('[data-llp-slide-number-display]').text(hash);
var newOrder = saveOrder(el);
console.debug(newOrder);
});
}
}).disableSelection();
}
In the context you mentioned it is invalid object in the javascript. And you couldn't push like this
slideOb = {slideId,slideNo};
slideOrder.push(slideOb);
First define slideOb is an valid object then push like below
slideOb = {'id': slideId, 'no':slideNo};
slideOrder.push(slideOb);
Now slideOrder is an local array it is always hold one array object. make it as global to push more arrays into it.

Creating coexisting objects in javascript

Is it possible to create multiple instances of an object in javascript such that they all are ready to be manipulated/edited at the same time? This relates to my earlier question here: Structure of orders in restaurant. What I am trying to do is keep each order object ready for editing until the customer is ready to pay/leave so that new items can be added to or existing items removed from them as desired - and it has to be possible for all order objects at the same time.
If the number of tables isn't very big - say, about 15 - would it be better to create a static array of 15 objects with different table numbers?
Er, yes - trivially (rough code warning):
// your class function
function MyClass(params)
{
this.foo = params.foo;
this.bar = params.bar;
// etc...
}
// object or array to maintain dynamic list o instances
var instances = [];
// create instances in storage object
instances.push(new MyClass({foo:123, bar:456}));
instances.push(new MyClass({foo:'abc', bar:'def'}));
// or alternately by key
instances['mykey'] = new Myclass({foo:'argle',bar'bargle'});
Don't create a static array because there's just no need when a dynamic structure is trivial enough. Perhaps I'm missing something from your question?
Edit: update with more illustrative code based on your earlier question, yet another way to solve the problem.
At this point however this is kind of a teaching thing only. If this was real application I would advise you to model all of this in a server side language - JS is really for controlling UI behaviour not business object modelling.
var Restaurant = {
Order : function (params)
{
this.id = params.id;
this.table = params.table;
this.items = [];
this.number_of_items = 0;
if(!Restaurant.Order.prototype.addItem)
{
Restaurant.Order.prototype.addItem = function (item)
{
// assuming name is unique let's use this for an associative key
this.items[item.name] = item;
this.number_of_items++;
//returning the item let's you chain methods
return item;
}
}
},
Item : function (params)
{
this.name = params.name;
this.quantity = params.quantity;
this.unit_price = params.unit_price;
if(!Restaurant.Item.prototype.price)
{
Restaurant.Item.prototype.price = function ()
{
return this.quantity * this.unit_price;
}
}
},
orders : [],
addOrder : function (order)
{
// assuming id is unique let's use this for an associative key
this.orders[order.id] = order;
//returning the item let's you chain methods
return order;
}
}
with (Restaurant)
{
with (addOrder( new Restaurant.Order({id:123, table:456}) )) // chaining!
{
addItem( new Restaurant.Item({name: 'foo', quantity: 10, unit_price: 10}) );
addItem( new Restaurant.Item({name: 'bar', quantity: 100, unit_price: 1}) );
}
}
var num_items = Restaurant.orders[123].items['foo'].price(); // returns 100
Since you are using object literals on your previous question, I suggest you to give a look to this prototypal inheritance technique, it will allow you to easily create new object instances inheriting from a base instance, for example:
// Helper function
if (typeof Object.create !== 'function') {
Object.create = function (o) {
function F() {}
F.prototype = o;
return new F();
};
}
// "Base" order object
var order = {
id: 0,
table: 0,
items: []
};
var orders = [], n = 10;
while (n--) { // make 10 objects inheriting from order and add them to an array
orders.push(Object.create(order));
}
Later on, you can access and manipulate your order objects in the orders array:
orders[0].id = 10;
orders[0].table = 5;
orders[0].items.push({
name: "Beer",
quantity: 1,
unit_price: 3
});

Categories