Understanding result returned from splice in CoffeeScript - javascript

I am using CoffeeScript along with the JS splice function. My understanding of the JS splice function is that it should return the objects that were spliced out and modify the original array. This seems to work ok with simple arrays but when I start adding objects to the array things break down. Below is a simplified case with comments:
And a link code
#Class that will go in array
class Thing
do: ->
alert "Hi"
a = new Thing
b = new Thing
arr = []
arr.push(a)
arr.push(b)
arr[0].do() # this works
result = arr.splice(0,1)
alert result.do() # this does not work
Does splice do something that makes this not work? If anyone has an idea about the reason this is happening and/or a fix, I would be very appreciative,

Array.splice() returns an array of the element(s) removed; as it has the potential to remove multiple via the second parameter:
Because of this, you should be using alert result[0].do();
Working example: http://jsfiddle.net/Cjtaa/

splice returns an array.
So you need to do:
result = arr.splice(0,1)
alert result[0].do()

Related

What is the difference between these two array assignments in Typescript?

I am working on Angular 4 application.
I found below code in my application but unable to find exact purpose of below code.
getManagementView(groupField: string) {
this.auditList = [...this.auditList.filter(this.filterByRevisit)];
}
I changed it to below code both are working fine.
getManagementView(groupField: string) {
this.auditList = this.auditList.filter(this.filterByRevisit);
}
Could any one help me to understand what is the difference in above two code blocks.
There is noting different. The spread (...) operator destroys the array and gives back the elements one by one and then in the [] put them into the making again an array. Which is actually extra operation.
So this.auditList.filter(this.filterByRevisit) returns an array,
and this [...this.auditList.filter(this.filterByRevisit)] returns an array which is spread and again makes an array.
I don't think there is a difference between the two. ... would create a new array, filter already did it.
However if I take the title:
this.array = this.array // does nothing, same object
this.array = [...this.array] // creates a new array, though the same content

When array length = 0, it stills shows as 1

I am dealing with an array that I want to delete an object from and return the new length of the array. For all other numbers, it works - but for one item, it does not. Not sure how to fix it so that the array length is 0 after the only object is deleted. My code is below:
Here's an example where I had one object in the 'player' array:
function deletecamera(id){
alert('before the splice, player length =' + player.length); //returns 1
delete player.splice((id),1);
i=0;
for (i=0;i<player.length;i++){
player.id=i;
}
alert('after reassigning, player length =' + player.length); // still returns 1?!
refreshlist();
}
the delete keyword doesn't remove the object from the array, it sets its value to undefined, so the size of the array stay the same.
See example here: http://jsfiddle.net/up5XX/
If you want to remove the first element from the array player using .splice, you can do this:
player.splice(0, 1);
yeah, thinking a bit more about this, I bet it will work if you change this line:
delete player.splice((id),1);
to
player.splice((id),1);
some weird codes there.
An array in JS is an object that can hold multiple [elements]. But just like with any other JS object you can add more members to it by just saying myArrayName.someMemberName = something. This will not be 'in' the array as if it was an element. This is even the JS poor mans way for an 'associative array’. This is what you are doing now with the .id = ...
You need to change
player.id = i;
into something like
player[i].id = i;
(or something like it. Don't know what the goal is there. I guess you want to reorder all Id's after deleting one in between.)
futhermore ... change the splice line to just this:
player.splice(id,1);
and remove the extra line with just:
i=0;
But I now realise these all are tips but no solution to your problem.
Can you please add
alert('trying to remove id ' + id);
and confirm that you do at least once try to delete id 0 ?

Javascript splice is removing everything but the element requested

I have a pretty simple script that takes content from an input box, makes an array out of it, removes a desired element, and spits back the text.
I'm trying to use "splice()" to remove the item but it removes everything BUT that one item:
var listOfTitles = $('.title-list').val();
var arrayOfTitles = listOfTitles.split(',');
var updatedTitles = arrayOfTitles.splice(2,1);
$('.title-list').val(updatedTitles.join());
for example if I have this:
test1,test2,test3,test4
I can turn it into an array. I want to removed "test3" and output "test1,test2,test4". The problem is, it's returning "test3" not removing it.
jsfiddle of what's happening: http://jsfiddle.net/C95kN/
Splice() modifies the array in place and returns an array with the elements you remove.
What you want is arrayOfTitles not updatedTitles
See working fiddle: http://jsfiddle.net/C95kN/1/
splice changes the passed array and returns the removed elements. Simply do
arrayOfTitles.splice(2,1);
$('.title-list').val(arrayOfTitles.join());
Note that I supposed the slice instead of splice was a typo.

Javascript "shift" versus "splice" - are these statements equal?

I just want to confirm if the following two Javascript statements produces the same results, as it seems to me:
First:
var element = my_array.splice(0,1)[0];
Second:
var element = my_array.shift();
I want to substitute the first by the second, in my own code, to improve readability. Can I do this?
They will have the same effect, yes. splice(0, 1) will remove the first element from my_array and return a new array containing that element. shift will do the same, but return the element itself, not an array.
shift is more readable (in my opinion) and is also significantly faster (in Chrome at least):
Both lines of code remove the first element from the array, and return the removed element, they are both supported in all major browsers.
You should use the second one, and the code will be more readable indeed.
shift returns the element that was removed, splice returns an array of elements that were removed.
that being said, the two statements do the same thing and i would agree that the second is more readable.
splice will return as an array but not remove data from the object instead make a copy
shift just give one data from front and also remove from object
For example,
const object = {1}
object.slice(); // return [{1}]
//object will be : {1}
object.shift(); // return {1}
//object will be : {} as shift remove the front data

Javascript collection of DOM objects - why can't I reverse with Array.reverse()?

What could be the problem with reversing the array of DOM objects as in the following code:
var imagesArr = new Array();
imagesArr = document.getElementById("myDivHolderId").getElementsByTagName("img");
imagesArr.reverse();
In Firefox 3, when I call the reverse() method the script stops executing and shows the following error in the console of the Web Developer Toolbar:
imagesArr.reverse is not a function
The imagesArr variable can be iterated through with a for loop and elements like imagesArr[i] can be accessed, so why is it not seen as an array when calling the reverse() method?
Because getElementsByTag name actually returns a NodeList structure. It has similar array like indexing properties for syntactic convenience, but it is not an array. For example, the set of entries is actually constantly being dynamically updated - if you add a new img tag under myDivHolderId, it will automatically appear in imagesArr.
See http://www.w3.org/TR/DOM-Level-2-Core/core.html#ID-536297177 for more.
getElementsByTag() returns a NodeList instead of an Array. You can convert a NodeList to an Array but note that the array will be another object, so reversing it will not affect the DOM nodes position.
var listNodes = document.getElementById("myDivHolderId").getElementsByTagName("img");
var arrayNodes = Array.slice.call(listNodes, 0);
arrayNodes.reverse();
In order to change the position, you will have to remove the DOM nodes and add them all again at the right position.
Array.prototype.slice.call(arrayLike, 0) is a great way to convert an array-like to an array, but if you are using a JavaScript library, it may actually provide a even better/faster way to do it. For example, jQuery has $.makeArray(arrayLike).
You can also use the Array methods directly on the NodeList:
Array.prototype.reverse.call(listNodes);
this problem can Actually be solved easily with array spread operator.
let elements = document.querySelectorAll('button');
elements = [...elements];
console.log(elements) // Before reverse
elements = elements.reverse(); // Now the reverse function will work
console.log(elements) // After reverse
<html>
<body>
<button>button1</button>
<button>button2</button>
<button>button3</button>
<button>button4</button>
<button>button5</button>
</body>
</html>
getElementsByTag() returns a NodeList instead of an Array. You need to convert the NodeList to an array then reverse it.
var imagesArr = [].slice.call(document.getElementById("myDivHolderId").getElementsByTagName("img"), 0).reverse();
I know this question is old but I think it needs a bit of clarification as some of the answers here are outdated as W3C changed the definition, and consequently the return value of these methods getElementsByTagName() and getElementsByClassName()
These methods as of the time of writing this answer return an object - empty or not - of type HTMLCollection and not NodeList.
It's like the difference between the properties children which returns an object of type HTMLCollection since it's only composed of elements and excluding text or comment nodes, and childNodes which returns an object of type NodeList since it could contain other node types like text and comments as well.
Note: I'd go on tangent here and express my lack of insight on why querySelectorAll() method currently returns a NodeList and not an HTMLCollection since it exclusively works on element nodes in the document and nothing else.
Probably it has something to do with potential coverage of other node types in the future and they went for a more future proof solution, who knows really? :)
EDIT: I think I got the rationale behind this decision to opt for a NodeList and not an HTMLCollection for the querySelectorAll().
Since they constructed HTMLCollection to be exclusively and entirely live and since this method doesn't need this live functionality, they decided for a NodeList implementation instead to best serve its purpose economically and efficiently.
Your first line is irrelevant, since it doesn't coerce the assignment to the variable, javascript works the other way. imagesArr, is not of Type Array(), its of whatever the return type of getElementsByTagName("img") is. In this case, its an HtmlCollection in Firefox 3.
The only methods on this object, are the indexers, and length. In order to work in reverse, just iterate backwards.
This worked for me, I did a reverse for loop and allocated the nodes to an array
var Slides = document.getElementById("slideshow").querySelectorAll('li');
var TempArr = [];
for (var x = Slides.length; x--;) {
TempArr.push(Slides[x]);
}
Slides = TempArr;

Categories

Resources