Jake Jake - 2 months ago 16
Javascript Question

JavaScript initializing/appending/updating array of arrays

I'm new to javascript and have been researching for quite a while now, but can't figure out this syntax. When I try to push an array into another array, it pushes the elements individually instead of creating an array of arrays like I want.

What I'm trying to do:

lastTimes
as array of arrays:

lastTimes = [[1, 12435235], [2,443531923], [3,4925951]]


if:
IDandTime = [5, 5959393]


append
IDandTime
to
lastTimes
as an array:

lastTimes = [[1, 12435235], [2,443531923], [3,4925951], [5, 5959393]]


or if ID (
IDandTime[0]
) already exists, update that array's time within
lastTimes
:

if
IDandTime = [1, 50305240]

update ID 1's time to 50305240:

lastTimes = [[1, 50305240], [2,443531923], [3,4925951], [5, 5959393]]


Would anyone mind helping me out here please? I've tried many combinations of syntaxes and can't get it right, nor have I been successful in figuring out the proper search term to find a preexisting answer. Any suggestions are greatly appreciated.

EDIT:

code:

var lastTimes = [];
var IDandTime = [1, 5935935];
lastTimes.push(IDandTime);


result:

lastTimes = [1, 5935935]


the result I want:

lastTimes = [[1, 5935935]]


EDIT2:

Ok here is the full function I am working with. I have a node.js server with an XBee serial module, and several Arduino temperature sensors with XBee serial modules. I have a handshake mechanism working, but I'm trying to achieve error checking for when nodes drop out, so their stale data is no longer used. I feel like this is really just a problem with basic 2D array syntax though.

// Open a new serial port connection
sp.on("open", function (err) {
if (err) {
return console.log('Error opening port: ', err.message);
}
console.log('open');


var nodeCount = 0;
var nodes = []; // get rid of after debugging
var lastTimes = [];
lastTimes[0] = [0,0]; // initalize as 2D array for later


// Grab data from buffer
sp.on('data', function(data) {
// Initialize time Object
var time = new Date();
// Split incoming data by newline
var buffer0 = data.split('\n');

// New node handshake initiation received
if (buffer0 == "BROADCASTING") {
nodeCount++;
var sendID = nodeCount.toString();
sp.write(sendID);
console.log("Broadcast received. Sending identifier #" + sendID);
nodes.push(nodeCount);
}

// Preconnected node data received
if ((buffer0 != "BROADCASTING") && (nodeCount > 0)) {
var receiveTime = time.getTime();
// [ID, Temp] touple
var nodeData = buffer0[0].split(" ");
console.log("NodeID: " + nodeData[0] + " Temp(F): " + nodeData[1]);
// [ID, Time] touple
var IDandTime = [];
IDandTime.push(nodeData[0]);
IDandTime.push(time.getTime());
console.log("IDandTime: " + IDandTime);

// Check for preexisting node ID
var oldNode = 0;
var nodeIndex = 0;
for (var i = 0; i < lastTimes.length; i++) {
if (lastTimes[i][0] == IDandTime[0]) {
oldNode = 1;
nodeIndex = i;
}
}
// If new node, add new node data to lastTimes (list of [ID, Time] touples)
if (oldNode == 0) {
lastTimes[lastTimes.length] = IDandTime;
console.log("lastTimes: " + lastTimes);
}
// If preexisting node, update preexisting node time
else if (oldNode == 1) {
lastTimes[i][1] = IDandTime[1];
}




}



});
});


error from my last attempt at finding the proper syntax:

lastTimes[i][1] = IDandTime[1];
^

TypeError: Cannot set property '1' of undefined

Answer

Firstly, if data is string, then calling data.split('\n') returns Array (see. String.prototype.split()), so each of your compares if (buffer0 == "BROADCASTING") are evaluated to false. You probably want to compare first line of the data, and first line is in buffer0[0], so write the conditions if (buffer0[0] == ... ).

Then you have error in code

// If preexisting node, update preexisting node time
else if (oldNode == 1) {
    lastTimes[i][1] = IDandTime[1];
}

where you are using variable i from loop, but because the loop is not terminated with break keyword, the loop is always going through the whole array and after the loop is finished, variable i is setted to lastTimes.length, which points to non existing index in the array.

I would write the loop like this:

var IDandTime = [];
var nodeIndex = nodeData[0];
IDandTime.push(nodeIndex);
IDandTime.push(time.getTime());

var foundAtIndex;
for (var i = 0, l = lastTimes.length; i < l; i++) {
    if (lastTimes[i][0] === nodeIndex) {
        foundAtIndex = i;
        break;
    }
}

if (typeof foundAtIndex === 'undefined') {
     lastTimes.push(IDandTime);
} else {
    lastTimes[foundAtIndex] = IDandTime;
}
Comments