Regular Jo
Regular Jo

Reputation: 5510

Overwriting a key, if it exists, in a key/value array

I'm allowing users to highlight rows in a table by clicking them.

When they click them, HighToggle() is called.

HighToggle() checks to to see if the bgcolor of the td matches the highlighter color and either highlights or un-highlights.

function HighToggle(cObj,vid,vColor,hColor) {
    if ((vColor == hColor)) {
      $(cObj).css('background-color','#FFFFFF'); // un-highlight
      vx.push({'id' : vid, 'status' : 'off'});
    } else {
      $(cObj).css('background-color','#' + Highlighter.Hex); // highlight
      vx.push({'id' : vid, 'status' : 'on'});
    }
}

It is important that I store these in an array, because I have recordset navigation that deletes the rows (from view) and loads in new rows via JSON. Otherwise, when I wanted to submit the data to the server, I could just loop through table rows and build the array pre-submit.

So, that works fine, except that it adds duplicate id's in the case of each time something is highlighted or un-highlighted, so it might look like:

1: on, 7: on, 7: off, 2: on, 4: on, 1: off, 3: on, 1: on, 2: off.

Which is just a mess.

Following the same click process that results in that array above, what I'd like to end up with is..

1: on, 7: off, 2: off, 4: on, 3: on

Rows never interacted with (5, 6, 8, 9, 10 if the result set only had 10 rows), need not have an entry in the array at all. I'm looking for a fast way to search my array and override rows if they exist.

I have thought of one solution that I haven't tried to implement yet because I feel like there might be something better.

I could make a separate array, let's say it's called vindexes. Vindexes could use the ID passed as the vid variable like so..

vindexes[vid] = vx.length;

HighToggle could check to see if vindexes[vid] exists, and if so, use that id to override rather than vx.push.

It would work (wouldn't it?) but is it reinventing the wheel? Is there a faster way? This function will be used a lot on each page.

I've found the grep function, since I'm using jQuery, but I don't think grep is applicable to me here since I want to know the index of where the ID was found.

Thank you for any advice.

Edit: Here's what I devised myself, though I think that the answer is a more elegant and sensible solution.

function HighToggle(cObj,vid,vColor,hColor) {
    vid = Number(vid);
    if (!(vid in vi)) {
      inIndex = vx.length;
    } else {
      inIndex = vi[vid];
    }

    if ((vColor == hColor)) {
      $(cObj).css('background-color','#FFFFFF');
      vi[vid] = inIndex;
      vx[inIndex] = {'id' : vid, 'status' : 'off'};
    } else {
      vi[vid] = inIndex;
      $(cObj).css('background-color','#' + Highlighter.Hex);
      vx[inIndex] = {'id' : vid, 'status' : 'on'};
    }
}

My solution, and the answer are both effective for my use, but perhaps someone else will run into this situation and benefit from the code I've provided.

Upvotes: 0

Views: 99

Answers (1)

James
James

Reputation: 22247

You could use an object:

var vx = {};

function HighToggle(cObj,vid,vColor,hColor) {
    if ((vColor == hColor)) {
      $(cObj).css('background-color','#FFFFFF'); // un-highlight
      vx[vid] = "off";
    } else {
      $(cObj).css('background-color','#' + Highlighter.Hex); // highlight
      vx[vid] = "on";
    }
}

Then if you need an array later (for submitting to server, etc):

var vxArray = [];
for (var key in vx) {
  vxArray.push({id: key, status: vx[key]});
}

Upvotes: 3

Related Questions