Most efficient way to parse a complex string in Javascript - javascript

I'm having trouble parsing this string.
newParams=[ "3","2","img1x:51","img1y:111","img1h:209","img1w:330","img1Px:231","img1Py:291","img1Dx:44","img1Dy:104","img2x:51","img2y:331","img2h:100","img2w:329","img2Px:274","img2Py:408","img2Dx:44","img2Dy:324","txt1x:399","txt1y:119","txt1h:103","txt1w:303","txtBox1x:391","txtBox1y:111","txtBox1h:119","txtBox1w:319","txt1Px:679","txt1Py:199","txt1Dx:392","txt1Dy:112","txt2x:399","txt2y:249","txt2h:103","txt2w:303","txtBox2x:391","txtBox2y:241","txtBox2h:119","txtBox2w:319","txt2Px:679","txt2Py:329","txt2Dx:392","txt2Dy:242","txt3x:399","txt3y:379","txt3h:44","txt3w:304","txtBox3x:391","txtBox3y:371","txtBox3h:60","txtBox3w:320","txt3Px:680","txt3Py:409","txt3Dx:392","txt3Dy:372"];
The string contains the height, width, x and y coordinates of both text objects and image objects that I need to position and resize in the DOM.
The first 2 values in the array are the number of textfields, and the number of images (which i was going to use in loops as the max number of iterations).
I need to parse the number values, and push them in these individual arrays.
var textXcoords = new Array();
var textYcoords = new Array();
var textHeight = new Array();
var textWidth = new Array();
var txtBoxXcoords = new Array();
var txtBoxYcoords = new Array();
var txtBoxHeight = new Array();
var txtBoxWidth = new Array();
var textPullXcoords = new Array();
var textPullYcoords = new Array();
var textDragXcoords = new Array();
var textDragYcoords = new Array();
var imgXcoords = new Array();
var imgYcoords = new Array();
var imgHeight = new Array();
var imgWidth = new Array();
var imgPullXcoords = new Array();
var imgPullYcoords = new Array();
var imgDragXcoords = new Array();
var imgDragYcoords = new Array();
For instance in "img1x:51" (image 1, Y coord), the number 51 would be pushed into the imgXcoords array at position 0.
and in "img2y:111" (image 2, Y coord), the number 111 would be pushed into the imgYcoords array at position 1.
and in "txt2w:303" (textfield 2, width), the number 303 would be pushed into the txtBoxWidth array at position 1.
If someone can show me just how to push the img(i)x and img(i)y values into their arrays (imgXcoords and imgYcoords) using a loop, I can figure out the rest from there.
I just don't know the most efficient way to search what I am looking for in the string and push it into the proper array.
I tried this for the x coordinates of the images, but my start and end positions are way off.
var iX1 = newParams.indexOf("img"+(1)+"x");
var iX2 = (iX1 + 7);
var res = newParams.substr(iX2,(iX2+2));
if I send "res" to the console.log, I get:
1","img1y:111","im as a result.
When I put that into a loop, and sub "1" with var i=0, it gets even more wacky.
Here is a jfiddle of my attempt: http://jsfiddle.net/S9RGH/

split is your friend. See if what I did here helps: jsfiddle
You can use split to segment the string into individual name/value pairs and put them in an array for easy access.

While this isn't what I could call the most efficient code, it is I believe the most readable solution...
I'd only work about optimizing it if it turned out to be a major performance hit. To optimize it, I'd go through the data object and turn it into a cleaner structure to parse.
var data = [
"3", "2", "img1x:51", "img1y:111", "img1h:209", "img1w:330", "img1Px:231", "img1Py:291", "img1Dx:44", "img1Dy:104", "img2x:51", "img2y:331", "img2h:100", "img2w:329", "img2Px:274", "img2Py:408", "img2Dx:44", "img2Dy:324", "txt1x:399", "txt1y:119", "txt1h:103", "txt1w:303", "txtBox1x:391", "txtBox1y:111", "txtBox1h:119", "txtBox1w:319", "txt1Px:679", "txt1Py:199", "txt1Dx:392", "txt1Dy:112", "txt2x:399", "txt2y:249", "txt2h:103", "txt2w:303", "txtBox2x:391", "txtBox2y:241", "txtBox2h:119", "txtBox2w:319", "txt2Px:679", "txt2Py:329", "txt2Dx:392", "txt2Dy:242", "txt3x:399", "txt3y:379", "txt3h:44", "txt3w:304", "txtBox3x:391", "txtBox3y:371", "txtBox3h:60", "txtBox3w:320", "txt3Px:680", "txt3Py:409", "txt3Dx:392", "txt3Dy:372"
];
var imgXcoords = [];
var imgYcoords = [];
var imgHeight = [];
var imgWidth = [];
var bucket;
// Trimmed for simplicty
// The names of the fields we are looking for
var fields = ["img?x", "img?y", "img?h", "img?w"];
// The arrays they go in.
// Keep these in the same order as the 'fields' above.
var dests = [imgXcoords,
imgYcoords,
imgHeight,
imgWidth
];
// Since the counts starts at '1'
var imageCount = +data[1] + 1;
// Go through the images
for (var i = 0; i < imageCount; i++) {
// And each field we are looking for
for (var ii = 0; ii < fields.length; ii++) {
// Make the name of the thing we are looking for.
var wantedKey = fields[ii];
wantedKey = wantedKey.replace("?", i);
// Then walk through the array. FUGLY
// I know, but simple.
for (var j = 0; j < data.length; j++) {
// Split the value up.
var arr = data[j].split(':');
if (arr) {
var currentKey = arr[0];
// Force to a number
var value = +arr[1];
console.log([currentKey, wantedKey]);
// we found what we want? Great!
if (currentKey === wantedKey) {
bucket = dests[ii];
bucket.push(value);
continue;
}
}
}
}
}
debugger;

Related

Changing one variable changes all others defined the same way

I have a JavaScript code which has 4 3-dimensional arrays that are each of 500x500x220 dimension (all 220 values in the last dimension are rarely all used). Because of this large dimension, it's much faster to define one array like this and then define the four arrays from that one. The problem is that then, when I change a value in one array, it changes in the others also. Here's my code:
<script type="text/javascript">
var content = new Array();
var signs = new Array();
var sens = new Array();
var props = new Array();
var ini = new Array();
for(i = 0; i < 500; i++){
ini[i] = new Array();
for(j = 0; j < 500; j++){
ini[i][j] = new Array();
}
}
content = ini;
signs = ini;
sens = ini;
props = ini;
function f(){
alert(signs[3][3][2]); //Returns undefined
content[3][3][2] = 2;
alert(signs[3][3][2]); //Returns 2
}
f();
</script>
Notice that the f() function is only supposed to change the content array but it also changes the signs array. Why does it do that and how do I get around it?
In case it makes a difference, I'm using HTA.
With the help of this post about copying nested arrays.
Your code:
content = ini;
signs = ini;
sens = ini;
props = ini;
makes the arrays to point to ini. That's why any reference to content[0], for instance, is a reference to signs[0] and ini[0] as well.
Use:
function copy(arr){
var new_arr = arr.slice(0);
for(var i = new_arr.length; i--;)
if(new_arr[i] instanceof Array)
new_arr[i] = copy(new_arr[i]);
return new_arr;
}
to copy the arrays:
content = copy(ini);
signs = copy(ini);
sens = copy(ini);
props = copy(ini);

Javascript add object to an oustide array in a loop

I'm trying to add dynamically created Javascript object to an array. I could traverse the DOM & creating the objects. But when displaying the final array of Objects, the count is correct but all objects are of same value ie, final index value. How to get rid of this problem?
PS: DOM traversal & other functionalities work well & only problem with creating the final array of objects with correct values.
Javascript Code.
var match = {};
var matches = [];
$('.SIsort').each(function (i, v) {
console.log("type.."+typeof matches);
var date = $(this).find('td:eq(0)').find('meta')[0].content;
var team1 = $(this).find('td:eq(1)').find('div:eq(1)').text();
var team2 = $(this).find('td:eq(1)').find('div:eq(3)').text();
var loc = $(this).find('td:eq(2)').find('div:eq(0)').text();
match.date = date;
match.team1 = team1;
match.team2 = team2;
match.venue = loc;
console.log(match); // It displays Correctly
(matches = window.matches || []).push({});
matches = (window.matches || []).push(match);
// console.log(matches[i])
});
console.log(matches); // All object values belong only to final index
You're repeatedly pushing the same object into the array.
Move your
var match = {};
...line into the loop so that you create a new object each time.
Also, I'm not sure what you're trying to achieve with this:
(matches = window.matches || []).push({});
matches = (window.matches || []).push(match);
But you just want:
matches.push(match);
Here's a minimal example of what you're doing:
var match = {};
var i;
for (i = 0; i < 5; ++i) {
match.i = i; // Overwrites the previous `i` value on subsequent loops
matches.push(match); // Pushes the *same object* onto the array
}
console.log(matches); // Shows the same object, all with `i = 4`
Instead, create a new object each time:
var i;
for (i = 0; i < 5; ++i) {
var match = {}; // Creates a new object
match.i = i;
matches.push(match);
}
console.log(matches);
Applying that to your code:
var matches = [];
$('.SIsort').each(function (i, v) {
console.log("type.."+typeof matches);
var date = $(this).find('td:eq(0)').find('meta')[0].content;
var team1 = $(this).find('td:eq(1)').find('div:eq(1)').text();
var team2 = $(this).find('td:eq(1)').find('div:eq(3)').text();
var loc = $(this).find('td:eq(2)').find('div:eq(0)').text();
var match = {};
match.date = date;
match.team1 = team1;
match.team2 = team2;
match.venue = loc;
console.log(match); // It displays Correctly
matches.push(match);
});
console.log(matches);
Side note: These lines:
var match = {};
match.date = date;
match.team1 = team1;
match.team2 = team2;
match.venue = loc;
console.log(match); // It displays Correctly
matches.push(match);
can be combined into:
var match = {
date: date,
team1: team1,
team2: team2,
venue: loc
};
console.log(match); // It displays Correctly
matches.push(match);
The problem with your code is that you're creating only ONE instance of match outside of your loop and updating the same object in each iteration before adding it to your Array. Actually you're supposed to create a NEW object, every time you want to add an entry to your loop, so create a new object at the starting of the loop like below.
var matches = [];
$('.SIsort').each(function (i, v) {
var match = {};
// update match object and add to array
matches.push(match);
}
That should do it :)

Combining multiple javascript arrays into JSON using Javascript

I have a handful of javascript arrays that I have no control over as far as format or variable names. I need to combine 6 of them into a json array. I have it pretty close but can't seem to get it to iterate through both the list of variables as well as the count of array elements.
It is apparent to me that I do not remember how to handle variables or iteration in JS as well as I used to and could really use some help.
The software whose output I needs to parse generates something similar to the following:
<script type="text/javascript">
var orderNum = 'OrderNum-485';
var orderSubTotal ='130.8';
var orderTotal ='130.8';
var numOfItems ='4';
var items =new Array('Item Name 1','Item Name 2','Item Name 3','Item Name 4');
var ids =new Array('item-id-1','item-id-2','item-id-3','item-id-4');
var codes =new Array('ITEM-CODE-1','ITEM-CODE-2','ITEM-CODE-3','ITEM-CODE-4');
var qtys =new Array('1','1','1','1');
var price =new Array('12.95','46.7','1.2','69.95');
var orderTax ='0';
var orderShipping ='0';
var appliedPromoIdList ='';
var coupon ='';
var storeId ='store_id';
var activeShipPromotionCount ='';
var itemImages =new Array('http://image_url','http://image_url','http://image_url','http://image_url');
</script>
Where as the software that I need to pass data too expects the following (as an object, I managed to get it done using strings):
[
{
"item_id":"item-id-1",
"desc":"ITEM-CODE-1",
"amount":"12.95",
"quantity":"1",
"name":"Item Name 1",
"image": "http://image_url",
{
"item_id":"item-id-2",
"desc":"ITEM-CODE-2",
"amount":"46.7",
"quantity":"1",
"name":"Item Name 2",
"image": "http://image_url",
]
This is what I came up with:
<script type="text/javascript">
var orderId = orderNum;
var createItemObjects = function() {
var keys = new Array ("item_id","desc","amount","quantity","name","image");
var yahooKeys = new Array ("ids","codes","price","qtys","items","itemImages");
var item,cartItems = [];
var c = numOfItems;
var k = yahooKeys.length;
var i = 0;
item = {};
for (; i < k; i++) {
var arrayName = yahooKeys[i].toString();
var buffer = eval('' + arrayName);
item[keys[i]] = buffer[0] //Ideally this should be the full range of 0-3 so that you can see each of the 4 items.
document.write("<br />Loop: "+i);
cartItems.push(item);
}
return cartItems;
It generates correctly formatted data but 6 identical copies of the element indicated by buffer's hard coded value
Something along the lines of :
function createItemObjects(items, ids, codes, qtys, prices, images) {
var check = items.length === ids.length && ids.length === codes.length &&
qtys.length === codes.length && prices.length === images.length;
if(!check) throw 'Arrays do not match';
var results = [];
for(var i = 0; i < items.length; ++i) {
results.push({
item_id: ids[i],
desc: codes[i],
amount: parseFloat(prices[i]),
name: items[i],
quantity: qtys[i],
image: images[i]
})
}
return results;
}
var data = generate(items, ids, codes, qtys, prices, itemImages);
var json_string = JSON.stringify(data);

How to extract values from an array of arrays in Javascript?

I have a variable as follows:
var dataset = {
"towns": [
["Aladağ", "Adana", [35.4,37.5], [0]],
["Ceyhan", "Adana", [35.8,37], [0]],
["Feke", "Adana", [35.9,37.8], [0]]
]
};
The variable has a lot of town data in it. How can I extract the first elements of the third ones from the data efficiently? I,e, what will ... be below?
var myArray = ...
//myArray == [35.4,35.8,35.9] for the given data
And what to do if I want to store both values in the array? That is
var myArray = ...
//myArray == [[35.4,37.5], [35.8,37], [35.9,37.8]] for the given data
I'm very new to Javascript. I hope there's a way without using for loops.
On newer browsers, you can use map, or forEach which would avoid using a for loop.
var myArray = dataset.towns.map(function(town){
return town[2];
});
// myArray == [[35.4,37.5], [35.8,37], [35.9,37.8]]
But for loops are more compatible.
var myArray = [];
for(var i = 0, len = dataset.towns.length; i < len; i++){
myArray.push(dataset.towns[i][2];
}
Impossible without loops:
var myArray = [];
for (var i = 0; i < dataset.towns.length; i++) {
myArray.push(dataset.towns[i][2][0]);
}
// at this stage myArray = [35.4, 35.8, 35.9]
And what to do if I want to store both values in the array?
Similar, you just add the entire array, not only the first element:
var myArray = [];
for (var i = 0; i < dataset.towns.length; i++) {
myArray.push(dataset.towns[i][2]);
}
// at this stage myArray = [[35.4,37.5], [35.8,37], [35.9,37.8]]

How do I divide a complex string into 3 seperate arrays?

Here's where I am:
I started with an array...cleaned it up using 'regex'.
Now I have this...each item has three values
mystring = 4|black|cat, 7|red|dog, 12|blue|fish
Here's where I want to be:
I want to end up with three arrays.
array1=("4","7","12")
array2=("black","red","blue")
array3=("cat","dog","fish")
I also want to do this without leaving the page...preferably using javascript
I understand the theory, but I'm getting tangled in the syntax.
I'd use John Resig's famous "search and don't replace" method here, it's perfect for it:
var arr1 = [], arr2 = [], arr3 = [],
mystring = "4|black|cat, 7|red|dog, 12|blue|fish";
mystring.replace(/(\d+)\|([^\|]+)\|([^,]+)/g, function ($0, $1, $2, $3) {
arr1.push($1);
arr2.push($2);
arr3.push($3);
});
Example
You want to use the split() method :
var res = mystring.split(','); //will give you an array of three strings
var subres = res[0].split('|'); //will give you an array with [4, black, cat]
//etc...
Like this?:
var values = mystring.split(',');
var arrays = new Array();
for(var i=0; i < values.length; i++) {
var parts = values[i].split('|');
for(var j = 0; j < parts.length;j++) {
if(!arrays[j]) {
arrays[j] = new Array();
}
arrays[j].push(parts[j]);
}
}
Will give you an array that contains those three arrays.
var str = '4|black|cat, 7|red|dog, 12|blue|fish';
var tmp = str.split(',');
var firstArray = Array();
var secondArray = Array();
var thirdArray = Array();
for( var i in tmp ){
var splitted = tmp[i].split('|');
//alert(true);
firstArray[i]=splitted[0];
secondArray[i]=splitted[1];
thirdArray[i]=splitted[2];
}

Categories

Resources