Deleting Particular Parts of a JSON - javascript

Was hoping someone may be able to point me in the right direction with this.
I have returned a list object in JSON format from .Net and then parse with JQuery.
var jsonOpens = $g.parseJSON(seriesReturn);
If I alert this I then receive the following:
1326531600000,8,49,1326531600000,8,49,1326535200000,11,169,1326535200000,11,169
What I then need to do with this is remove the second column.
I managed to do that by looping through and deleting
for (var i = 0; i < jsonOpens.length; i++) {
delete jsonOpens[i] [1];
}
This works but still leaves the column in place i.e alerts:
1326531600000,,49,1326531600000,,49,1326535200000,,169,1326535200000,,169
I tried doing a replace by replacing the double commas with single commas but this doesn't work in this format.
What would be the best way for me to identify a column and remove it completey whilst keeping the same format?

Assuming it's a JS array, you should be able to use the .splice() method to remove the appropriate elements:
http://www.w3schools.com/jsref/jsref_splice.asp
So, your loop would be (I think)
for (var i = 0; i < jsonOpens.length; i++) {
jsonOpens[i].splice(1,1);
}

Related

Searching for a string on a website to display odds

I'm trying to display only the odds from bet365 from a javacript piece of code. I can only think of doing this by searching for a part of the id of the bet, each bookie has its own related ids and bet365's is b3, so this query below I've tried to search for ids where the string includes the "b3" in it, as all other parts of it seem completely random
http://www.oddschecker.com/horse-racing/2015-06-30-chepstow/18:10/winner
var odds = document.getElementsByTagName("odds");
for (var i = 0; i < odds.length; i++) {
if(odds[i].id.indexOf("b3") == 0) {
odds[i].disabled = bDisabled;
}
}
Whenever I do this my return says undefined. How can I get this to work
It looks like the marker you're looking for is .co, from what I can see from the code (delimiting a td with the odds as inner content).
The site also has jQuery loaded up, so let's use jQuery to simplify the pseudo-code (we can always transform it to pure javascript later):
var odds = $('.co');
odds.each(function(){
var id = $(this).attr('id');
if(id.indexOf('_B3') >= 0){
console.log(id);
//your code here
}
});
Given that the ID is not at the end of the ID string, we can't check to see if the indexOf is == to 0; instead, we just want to know if the ID we're looking for (b3) is contained in that string. So we're looking for any value that is not -1, the value returned by indexOf when the query is not found in the original string.
I'm searching for specifically for _B3 for two reasons: One, indexOf is case sensitive, so given that your ID are uppercase, we must make our search uppercase too. I'm also adding the underscore in order to respect the ID string format, as I'm not 100% certain that your ID will only contain letters to delimit IDs from the bet vendor, so we can't be too safe with that.
In pure javascript:
var odds = document.getElementsByClassName('co');
for(var ii = 0; ii < odds.length; ii++){
if(odds[ii].id.indexOf("_B3") >= 0){
console.log(odds[ii].id);
//your code here
}
}

Using a String as HTML

I've been trying to create a news box for my website today and I have a problem. Let me explain what happens. I create a 2d array that contains the news (date and the news). I then loop through it to construct the news_string and then use that for the DIV's innerHTML. I have put a very simple version of it below
for (var i = 0; i < news.length; i++)
{
news_string.concat(news[i][1],"<br>");
}
document.getElementById("news-content").innerHTML = news_string;
However nothing appears. I have cut it down to the very minimal. No result. I have used alerts. Nothing appears. The news_string is blank regardless of the fact I put data into it. And even if I do gain a string nothing appears in the DIV box. What's causing this massive break?
The concat method returns a value, you have no variable assignement there to catch it...
From the docs (notice the bold part):
The concat() method combines the text of two or more strings and returns a new string.
So you should use:
news_string = news_string.concat(news[i][1],"<br>");

Eliminate duplicate elements fetched from a table and inserted into array

I ran over many questions in stackoverflow but none seemed to help me. I know there are many like this post, but I'm in need of help.
I'm trying to get a table's column into array and then I'm trying to remove duplicate elements. This jsfiddle illustrates the situation. Here's the code:
//sorry for the language
var days2 = ["Pazartesi", "Salı", "Pazartesi", "Çarşamba"];
var days = jQuery.makeArray($(".dersprg tr td:nth-child(6)"));
//the function works just fine on days2 array, but not on days array
function eliminateRepeat(array){
var i, j;
for(i=0 ; i<array.length ; i++){
for(j=i+1 ; j < array.length ; j++){
if(array[i] == array[j])
array.splice(j,1);
}
}
}
eliminateRepeat(days);
$(days).clone().appendTo(document.getElementById("test"));
The table I used is sort of huge for here, you'd better see it from jsfiddle.
Note: I used many functions written as answers to other questions, none seemed to work for me. I wrote my own function finally, which works fine on a string based array, however it still can not make the job done with a selected html element based array.
the function works just fine on days2 array, but not on days array
Yes, since there are no duplicates in the elements list. There may be some with the same text, but they are different nodes and do not equal with the == operator. You would need to change
if(array[i] == array[j])
to
if($(array[i]).text() == $(array[j]).text())
Btw, your splice removes one element from the array so that all indizes change. Yet, by going to the next index you are going to jump over one item. Use array.splice(j--,1);

Better way of splitting and assigning many values in Javascript?

I have a for loop that cycles through the number of elements that the user has created. There are a lot of available settings in this plugin, and each element can receive it's specific settings.
User settings are entered in the following format: speed_x: "1000,500 > 1000,200 > 0,0"
This controls the speed_x in/out for 3 separate elements. The > divides by object and the commas separate the in/out.
So I can grab specific object speed_x values, I've split speed_x into speed_x_set (splitting by >) resulting in:
1 1000,500
2 1000,200
3 0,0`
3 Inside the loop, I grab the value by index (since it's the object #) and split it by comma (to get speed_x_in and speed_x_out.)
for(var i=0; i<OS.numberofobjects; ++i){
OS.speed_x_on_set[i]=speed_x_set[i].split(",")[0],
OS.speed_x_off_set[i]=speed_x_set[i].split(",")[1],
...
};
Everything is assigned by object and by setting in/out correctly into the master OS settings object. T*he problem is I have many, many settings which need to be split in this fashion...* for example: delay_x_set, speed_y_set, opacity_set, etc. Their names are all based on the default setting name, with "_set" added as shown above. Hopefully this provides enough information. Thanks!
I would avoid to access to the same item twice and perform the same split twice for each iteration. So, you could have something like:
for (var i = 0, item; item = speed_x_set[i++];) {
var values = item.split(",");
OS.speed_x_on_set.push(values[0]);
OS.speed_x_off_set.push(values[1]);
}
Notice that in JavaScript 1.7 (Firefox) you can simply have:
for (var i = 0, item; item = speed_x_set[i++];) {
var [on, off] = item.split(",");
OS.speed_x_on_set.push(on);
OS.speed_x_off_set.push(off);
}
And hopefully in the next version of ECMAScript as well.
It's called "destructuring assignment".
I would say to cache the split result
for(var objindex=0; objindex<OS.numberofobjects; ++objindex){
var splits = speed_x_set[objindex].split(","); //Cache the split so its does not need to be done twice
OS.speed_x_on_set[objindex] = splits[0];
OS.speed_x_off_set[objindex] = splits[1];
...
};
What you're looking for is called parallel assignment, but unfortunately, JavaScript doesn't have it.
In ruby, however, it is common to see similar patterns:
first, second = "first second".split
As others have noted, the obvious way would be to cache split results and assign them separately. Sorry for not answering your question directly.

Removing items from data bound array

How do I remove an items from a data bound array? My code follows.
for(var i = 0; i < listBox.selectedIndices.length; i++) {
var toRemove = listFiles.selectedIndices[i];
dataArray.splice(toRemove, 1);
}
Thanks in advance!
Edit Here is my swf. The Add Photos works except when you remove items.
http://www.3rdshooter.com/Content/Flash/PhotoUploader.html
Add 3 photos different.
Remove 2nd photo.
Add a different photo.
SWF adds the 2nd photo to the end.
Any ideas on why it would be doing this?
Edit 2 Here is my code
private function OnSelectFileRefList(e:Event):void
{
Alert.show('addstart:' + arrayQueue.length);
for each (var f:FileReference in fileRefList.fileList)
{
var lid:ListItemData = new ListItemData();
lid.fileRef = f;
arrayQueue[arrayQueue.length]=lid;
}
Alert.show('addcomplete:' + arrayQueue.length);
listFiles.executeBindings();
Alert.show(ListItemData(arrayQueue[arrayQueue.length-1]).fileRef.name);
PushStatus('Added ' + fileRefList.fileList.length.toString() + ' photo(s) to queue!');
fileRefList.fileList.length = 0;
buttonUpload.enabled = (arrayQueue.length > 0);
}
private function OnButtonRemoveClicked(e:Event):void
{
for(var i:Number = 0; i < listFiles.selectedIndices.length; i++) {
var toRemove:Number = listFiles.selectedIndices[i];
//Alert.show(toRemove.toString());
arrayQueue.splice(toRemove, 1);
}
listFiles.executeBindings();
Alert.show('removecomplete:' + arrayQueue.length);
PushStatus('Removed photos from queue.');
buttonRemove.enabled = (listFiles.selectedItems.length > 0);
buttonUpload.enabled = (arrayQueue.length > 0);
}
It would definitely be helpful to know two things:
Which version of ActionScript are you targeting?
Judging from the behavior of your application, the error isn't occurring when the user removes an item from the list of files to upload. Looks more like an issue with your logic when a user adds a new item to the list. Any chance you could post that code as well?
UPDATE:
Instead of: arrayQueue[arrayQueue.length]=lid
Try: arrayQueue.push(lid)
That will add a new item to the end of the array and push the item in to that spot.
UPDATE 2:
Ok, did a little more digging. Turns out that the fileList doesn't get cleared every time the dialog is opened (if you're not creating a new instance of the FileReferenceList each time the user selects new files). You need to call splice() on the fileList after you add each file to your Array.
Try something like this in your AddFile() method...
for(var j:int=0; j < fileRefList.fileList.length; j++)
{
arrayQueue.push(fileRefList.fileList[j]);
fileRefList.fileList.splice(j, 1);
}
That will keep the fileList up to date rather than holding on to previous selections.
I see one issue. The selected indices are no longer valid once you have spliced out the first element from the array. But that should only be a problem when removing multiple items at once.
I think we need to see more code about how you are handling the upload before we can figure out what is going on. It looks to me like you are holding a reference to the removed FileReference or something. The described problem is occurring when you upload a new file, not when you remove the selected one.
Do you mean to use listBox and listFiles to refer to the same thing?
I'm stepping out on a limb here, because I don't have a ton of experience with JavaScript, but I'd do this the same way that I'd do it in C, C++, or Java: By copying the remaining array elements down into their new locations.
Assuming that listFiles.selectedIndices is sorted (and its contents are valid indices for dataArray), the code would be something like the following:
(WARNING: untested code follows.)
// Don't bother copying any elements below the first selected element.
var writeIndex = listFiles.selectedIndices[0];
var readIndex = listFiles.selectedIndices[0] + 1;
var selectionIndex = 1;
while(writeIndex < (dataArray.length - listFiles.selectedIndices.length)) {
if (selectionIndex < listFiles.selectedIndices.length) {
// If the read pointer is currently at a selected element,
// then bump it up until it's past selected range.
while(selectionIndex < listFiles.selectedIndices.length &&
readIndex == listFiles.selectedIndices[selectionIndex]) {
selectionIndex++;
readIndex++;
}
}
dataArray[writeIndex++] = dataArray[readIndex++];
}
// Remove the tail of the dataArray
if (writeIndex < dataArray.length) {
dataArray.splice(writeIndex, dataArray.length - writeIndex);
}
EDIT 2009/04/04: Your Remove algorithm still suffers from the flaw that as you remove items in listFiles.selectedIndices, you break the correspondence between the indices in arrayQueue and those in listFiles.selectedIndices.
To see this, try adding 3 files, then doing "Select All" and then hit Remove. It will start by removing the 1st file in the list (index 0). Now what had been the 2nd and 3rd files in the list are at indices 0 and 1. The next value taken from listFiles.selectedIndices is 1 -- but now, what had been the 3rd file is at index 1. So the former File #3 gets spliced out of the array, leaving the former 2nd file un-removed and at index 0. (Using more files, you'll see that this implementation only removes every other file in the array.)
This is why my JavaScript code (above) uses a readIndex and a writeIndex to copy the entries in the array, skipping the readIndex over the indices that are to be deleted. This algorithm avoids the problem of losing correspondence between the array indices. (It does need to be coded carefully to guard against various edge conditions.) I tried some JavaScript code similar to what I wrote above; it worked for me.
I suspect that the problem in your original test case (removing the 2nd file, then adding another) is analogous. Since you've only shown part of your code, I can't tell whether the array indices and the data in listFiles.selectedIndices, arrayQueue, and fileRefList.fileList are always going to match up appropriately. (But I suspect that the problem is that they don't.)
BTW, even if you fix the problem with using splice() by adjusting the array index values appropriately, it's still an O(N2) algorithm in the general case. The array copy algorithm is O(N).
I'd really need to see the whole class to provide a difinitive answer, but I would write a method to handle removing multiple objects from the dataProvider and perhaps assigning a new array as the dataProvider for the list instead of toying with binding and using the same list for the duration. Like I said, this is probably inefficient, and would require a look at the context of the question, but that is what I would do 9unless you have a big need for binding in this circumstance)
/**
* Returns a new Array with the selected objects removed
*/
private function removeSelected(selectedItems:Array):Array
{
var returnArray:Array = []
for each(var object:Object in this.arrayQueue)
{
if( selectedItems.indexOf(object)==-1 )
returnArray.push( object )
}
return returnArray;
}
You might be interested in this blog entry about the fact that robust iterators are missing in the Java language.
The programming language, you mentioned Javascript, is not the issue, it's the concept of robust iterators that I wanted to point out (the paper actually is about C++ as the programming language).
The [research document]() about providing robust iterators for the ET++ C++ framework may still e helpful in solving your problem. I am sure the document can provide you with the necessary ideas how to approach your problem.

Categories