JS: inserting element into array - javascript

I have the following function. It is expected to insert item into array at position no. When item is inserted, the last element of the array is dropped, i.e. array must always have the same length. Array is taken from string session variable itemstr using split(). The very first element of the array is to be never changed, so I always call this function starting with n===1. The problem is that the function doesn't insert in the sense of splice(). It simply changes the value of element #no
function insert_into_array(no, item)
{
var itemarr = sessionStorage.itemstr.split(',');
if ((no < itemarr.length) && (no > 0)) {
var i;
for (i === itemarr.length - 1; i > no; i--) {
itemarr[i] = itemarr[i - 1];
}
itemarr[no] = item;
sessionStorage.itemstr = itemarr.toString();
}
}

In this line you have a type:
for (i === itemarr.length - 1; i > no; i--) {
It should be actually: i = itemarr.length - 1 and not i === itemarr.length - 1

Not getting what you exactly want.. What i understand is that you need to insert element at position defined by no and remove last element. You can try this in case..
function insert_into_array(no, item)
{
var itemarr = sessionStorage.itemstr.split(',');
if ((no < itemarr.length) && (no > 0)) {
itemarr .splice(no, 0, item); //Insert element at position defined by #no
itemarr .pop(); //removes last element
}
sessionStorage.itemstr = itemarr.toString();
}

Culprit for your function is following line
for (i === itemarr.length - 1; i > no; i--)
here i will be assigned to the value undefined since this is a comparison(===) and not assignment (=). Thus i(undefined) > no will always be false , so no more loop execution.
Simply replace comparison with assignment
for (i = itemarr.length - 1; i > no; i--)

As i understood from the question, you want to insert a variable to an array at a fixed position,and previous content at that position need to shifted and last array value need to be removed.
just use arr.pop() to remove last element and make use of a for loop to shift one position to right.
using jQuery will be more simple here.

Related

Skipping multiple elements in a FOR loop, Javascript

I have some file contents I'd like to pass on to my server using a javascript function. In the file, there are many empty lines, or those which contain useless text. So far I read every line in as a string stored in an array.
How do I then loop through that content skipping multiple lines such as lines 24,25, 36, 42, 125 etc. Can I put these element id's into an array and tell my for loop to run on every element except these?
Thanks
you can't tell your for loop to iterate all, but skip certain elements. it will basically just count in any direction (simplified) until a certain critera has been met.
you can however put an if inside your loop to check for certain conditions, and chose to do nothing, if the condition is met. e.g.:
(pseudo code below, beware of typing errors)
for(var line=0; line < fileContents.length; line++) {
if(isUselessLine(line)) {
continue;
}
// process that line
}
the continue keyword basically tells the for loop to "jump over" the rest of the current iteration and continue with the next value.
The isUselessLine function is something you'll have to implement yourself, in a way, that it returns true, if the line with the given linenumber is useless for you.
You can try this its not much elegent but will suerly do the trick
<html>
<body>
<p>A loop which will skip the step where i = 3,4,6,9.</p>
<p id="demo"></p>
<script>
var text = "";
var num = [3,4,6,9];
var i;
for (i = 0; i < 10; i++) {
var a = num.indexOf(i);
if (a>=0) {
continue;
}
text += "The number is " + i + "<br>";
}
document.getElementById("demo").innerHTML = text;
</script>
</body>
You could use something like this
var i = 0, len = array1.length;
for (; i < len; i++) {
if (i == 24 || i == 25) {
array1.splice(i, 1);
}
}
Or you can have an another array variable which got all the items that need to be removed from array1
Another method:
var lines = fileContents.match(/[^\r\n]+/g).filter(function(str,index,arr){
return !(str=="") && uselessLines.indexOf(index+1)<0;
});
If you have many indices to skip, and this depends on the elements of the array, you could write a function that returns the number of elements to skip over for each index in that array (or returns 1, if no skipping required):
for ( let i = 0;
i < array.length;
i += calcNumberOfIndicesToSkip( array, i )){
// do stuff to the elements that aren't
// automatically skipped
}
function calcNumberOfIndicesToSkip( array, i ){
// logic to determine number of elements to skip
// (this may be irregular)
return numberOfElementsToSkip ;
}
In your case:
// skip the next index (i+1)?
for ( let i=0; i<array.length; i+=skipThisIndex(i+1) ){
// do stuff
}
function skipThisIndex(i){
const indicesToSkip = [ 24, 25, 36, 42, 125 ];
return 1 + indicesToSkip.includes(i);
}
// returns 1 if i is not within indicesToSkip
// (there will be no skipping)
// => (equivalent to i++; normal iteration)
// or returns 1 + true (ie: 2) if i is in indicesToSkip
// => (index will be skipped)

Problems with the "+" and "-" operators

The problem is the - operator does not working (in 8th line). See my code below:
array = [0,0,0,0,3,0,0,0,0],
n = 0;
for(var i = 0; i < array.length; i++){
if(n < 9){ //the "n" variable there's only for don't crash the browser with a infinite loop
if(array[i] == 3){
array[i] = 0;
array[i - 1] = 3; //I believe that here is the problem
}
}
n++;
}
console.log(array);
So... I want to move the "3" value to the beginning of the array. But it only work if I use the + operator(in 8th line). Consequently, if I use the + one, the "3" value goes to the end of the array.
Anyone know why the - operator does not working in this case and the + works?
If you change line 8 to:
array[i+1] = 3;
then the number 3 will go all the way to the end of the array (well, beyond the end of the array and I'll be damned to find out what Javascript does then!). This is because the loop traverses the array in increasing order and the position i+1 will be checked right next.
On the other hand, with your current line 8, number 3 goes one position backwards (which has already been checked), so it doesn't go all the way to the beginning of the array, just one position. If you want it to go to all the way in the same fashion, you should reverse the loop (make it traverse the array in descending order of the position i).
What do you think happens when i is 0 and you do - 1?
In your first iteration of the loop, when i is zero, (i - 1) is -1, so you're trying to access array[-1], which is invalid.
Okay, instead of answering "Anyone know why the - operator does not working in this case and the + works?", I will answer what I think is the real question, as stated in the original post: I want to move the "3" value to the beginning of the array. I think this does what is desired:
var array = [0,0,0,0,3,0,0,0,0];
var first_val = 3;
var index = array.indexOf(first_val);
if (index > 0) {
array.splice(index, 1);
array.unshift(first_val);
}
console.log(array);
Inspired by this.
I want to move the "3" value to the beginning of the array
Use the correct answer provided in here. Then use .indexOf() to move it.
Array.prototype.move = function (old_index, new_index) {
if (new_index >= this.length) {
var k = new_index - this.length;
while ((k--) + 1) {
this.push(undefined);
}
}
this.splice(new_index, 0, this.splice(old_index, 1)[0]);
return this; // for testing purposes
};
var array = [0,0,0,0,3,0,0,0,0];
var result = array.move(array.indexOf(3),0);
console.log(result);
JSFiddle Demo

cross browser remove element from an array

I have an array of numbers which are values of the data-cardNumber attribute of different element in my site.
I'm trying to remove the value of the data-cardNumber attribute of the element that has that attribute that also has the class .lastBeenDragged.
I am trying this, but I think I may have oversimplified my code too much.
When I console.log the array before and after executing this code there is no change in the array.
How can I properly and cross browserly remove an element, the value of the data-cardNumber of the element with the class .lastBeen Dragged, from the array swipedAwayCards ?
Here is the code:
if(swipedAwayCards.indexOf($('.lastCardDragged').attr('data-cardNumber')) > -1) swipedAwayCards.splice(swipedAwayCards.indexOf($('.lastCardDragged').attr('data-cardNumber')), 1);
Since Array.indexOf() is not supported crossbrowser, you can user $.inArray()
var index = $.inArray($('.lastCardDragged').attr('data-cardNumber'), swipedAwayCards);
if (index > -1) {
swipedAwayCards.splice(index, 1);
}
Try this :
var v = $('.lastCardDragged').attr('data-cardNumber');
for (var i = 0, l = swipedAwayCards.length; i < l; i++) {
if (swipedAwayCards[i] == v) {
swipedAwayCards.splice(i, 1);
break;
}
}

How to keep Javascript array sorted, without sorting it

I have a Node.js application where I have to very often do following things:
- check if particular array already contains certain element
- if element does exist, update it
- if element do not exist, push it to the array and then sort it using underscore _.sortBy
For checking if the element already exists in the array, I use this binary search function:
http://oli.me.uk/2013/06/08/searching-javascript-arrays-with-a-binary-search/
In this way, when the size of the array grows, the sorting becomes slower and slower.
I assume that the array size might grow to max 20 000 items per user. And eventually there will be thousands of users. The array is sorted by a key, which is quite a short string. It can be converted into integer if needed.
So, I would require a better way to keep the array sorted,
in stead of sorting it every time new element is pushed onto it.
So, my question is, how should/could I edit the binary search algorithm I use, to enable me to
get the array index where the new element should be placed, if it doesn't already exist in the array?
Or what other possibilities there would be to achieve this. Of course, I could use some kind of loop that would start from the beginning and go through the array until it would find the place for the new element.
All the data is stored in MongoDB.
In other words, I would like to keep the array sorted without sorting it every time a new element is pushed.
It's easy to modify this binaryIndexOf function to return an index of the next element when no matches found:
function binaryFind(searchElement) {
'use strict';
var minIndex = 0;
var maxIndex = this.length - 1;
var currentIndex;
var currentElement;
while (minIndex <= maxIndex) {
currentIndex = (minIndex + maxIndex) / 2 | 0; // Binary hack. Faster than Math.floor
currentElement = this[currentIndex];
if (currentElement < searchElement) {
minIndex = currentIndex + 1;
}
else if (currentElement > searchElement) {
maxIndex = currentIndex - 1;
}
else {
return { // Modification
found: true,
index: currentIndex
};
}
}
return { // Modification
found: false,
index: currentElement < searchElement ? currentIndex + 1 : currentIndex
};
}
So, now it returns objects like:
{found: false, index: 4}
where index is an index of the found element, or the next one.
So, now insertion of a new element will look like:
var res = binaryFind.call(arr, element);
if (!res.found) arr.splice(res.index, 0, element);
Now you may add binaryFind to Array.prototype along with some helper for adding new elements:
Array.prototype.binaryFind = binaryFind;
Array.prototype.addSorted = function(element) {
var res = this.binaryFind(element);
if (!res.found) this.splice(res.index, 0, element);
}
If your array is already sorted and you want to insert an element, to keep it sorted you need to insert it at a specific place in the array. Luckily arrays have a method that can do that:
Array.prototype.splice
So, once you get the index you need to insert at (you should get by a simple modification to your binary search), you can do:
myArr.splice(myIndex,0,myObj);
// myArr your sorted array
// myIndex the index of the first item larger than the one you want to insert
// myObj the item you want to insert
EDIT: The author of your binary search code has the same idea:
So if you wanted to insert a value and wanted to know where you should
put it, you could run the function and use the returned number to
splice the value into the array.
Source
I know this is an answer to an old question, but the following is very simple using javascripts array.splice().
function inOrder(arr, item) {
/* Insert item into arr keeping low to high order */
let ix = 0;
while (ix < arr.length) {
//console.log('ix',ix);
if (item < arr[ix]) { break; }
ix++;
}
//console.log(' insert:', item, 'at:',ix);
arr.splice(ix,0,item);
return arr
}
The order can be changed to high to low by inverting the test

Trying to search through array of strings for a pattern the user inputs - javascript

var p = ["array of words", "i really hate the sun", "i'm TIred"]
function findword(contents,pattern){
var answer;
var idx;
var counter = 0;
var pat_lc = pattern.toLowerCase();
for (var i = 0; i <= contents.length-1; i++){
var str_lc = contents[i].toLowerCase();
idx = str_lc.indexOf(pat_lc)
if (idx >= 0){
answer = i
}
else{
answer = "-1"
}
}
alert(answer)
}
findword(p,"words")
I'm trying to find the index of the array for a certain word, in an array of strings, however it only works for certain words in the array above. For example, on the last line of the code, when I chose to search for "words" it returns the value of "answer" and "idx" -1 when it should be 0 and 9 respectively. However, when I search for "tired", the value of "answer" is 2 and "idx" is 4 (which is correct). Why do some words work and others return the value of -1?
Here's a modified working version that will find all matches
var p = ["array of words", "i really hate the sun", "i'm TIred"]
function findword(contents,pattern){
var matches=[];
var idx;
var pat_lc = pattern.toLowerCase();
for (var i = 0; i <= contents.length-1; i++){
var str_lc = contents[i].toLowerCase();
idx = str_lc.indexOf(pat_lc)
if (idx >= 0){
matches.push({ idx: i, position: idx})
}
}
return matches
}
Several problems
answer and idx get overwritten ever pass of the for loop. So regardless if a match was found...only last pass is returned. I saved the results into separate array that gets returned. Code you provided didn't do anything with idx.
Can test output for length to see if matches exist...no matches will return empty array with no length
Come to think of it...not sure what output you want
DEMO
You should stop as soon as you find a solution.
Your program only stops when it iterated over the whole array. But what if the answer what not in the last element ? Then answer will contain -1.
You can init answer at -1 and continue your for loop as long as i is less than content.length and answer is equal to -1 : http://jsfiddle.net/#&togetherjs=dbVcN8JkKP

Categories

Resources