Fastest way to move first element to the end of an Array - javascript

I'm wondering what is the fastest way in JavaScript to move an element from the beginning of an Array to the end. For example if we have
[8,1,2,3,4,5,6,7]
And we want: [1,2,3,4,5,6,7,8]
I want to move the first element to the end. I was thinking about switching element 0 with element 1, after that switching element 1 with element 2 and so on until the 8 is at the and (basically how bubblesort works). I was wondering if there is a faster way to bring the first element to the end.
I will be using small Arrays (around 10 elements), and I want to avoid shift() since it's pretty slow.
This is what I have now on chrome it's 45% faster than normal shift+push: http://jsperf.com/shift-myfunc
The arrays will have objects in them for a game.

Use the shift() and push() functions:
var ary = [8,1,2,3,4,5,6,7];
ary.push(ary.shift()); // results in [1, 2, 3, 4, 5, 6, 7, 8]
Example:
var ary = [8,1,2,3,4,5,6,7];
console.log("Before: " + ary);
ary.push(ary.shift()); // results in [1, 2, 3, 4, 5, 6, 7, 8]
console.log("After: " + ary);

Use shift and push
var a = ["a","b","c"];
var b = a.shift();
a.push(b);
or
var b = a.shift();
a[a.length] = b;
Edit Based on updated question
What is going to be the fastest? Really depends on content of the array and what browser/version!
Now what are the ways to remove the first index?
shift()
splice()
slice()
Now what are the ways to add to the last index?
push()
array[array.length]
concat() -- not even going to try
Other ways
for loop - make new array [going to be horrible on large arrays]
JSPerf:
http://jsperf.com/test-swapping-of-first-to-last
What is really the fastest?
What is the fastest really depends on what you are doing with the array. If you are just using the first index, it will be fastest just to make your code read an index and not shift the values. If you are using all the indexes, than just loop and through and when you get to the end start back at zero. Basic counters.

And here is a sweet ES6 version
let arr = [1,2,3,4,5,6]
const [first, ...rest] = arr;
arr = [...rest,first]

Use splice to get the first element
var first = array.splice(0,1);
Then push to make if the last.
Since the return value of the splice method is an array, you have to say
array.push(first[0]);
Working example here: JSFIDDLE

Just in case you want to put any element to the end:
var ary = [8,1,2,3,4,5,6,7];
ary.push(ary.splice(position, 1)[0]);
for position just wrap this in a forEach.

var a = [1,2,3,4,5,6,7,8];
var b= a[7];
var c = a.slice(1, 8);
c.push(b);
Edit: It's probably better to just shift, like epascarello did in his answer.

With ES20...
const newArr = [
...arr.slice(1),
arr[0]
];

one more flavour
var arr = [0, 1, 2];
arr = arr.concat(arr.shift())
concat can add not just a element but another array at the end or beginning

Updating the arrays moving elements from one extreme to the other:
const array = ['First', 'Second', 'Third', 'Fourth'];
const next = [...array]
next.push(next.shift())
console.log(next); // [ 'Second', 'Third', 'Fourth', 'First' ]
const prev = [...array]
prev.unshift(prev.pop())
console.log(prev); // [ 'Fourth', 'First', 'Second', 'Third' ]

Related

Rotate multiple banner images [duplicate]

By default the indexing of every JavaScript array starts from 0. I want to create an array whose indexing starts from 1 instead.
I know, must be very trivial... Thanks for your help.
It isn't trivial. It's impossible. The best you could do is create an object using numeric properties starting at 1 but that's not the same thing.
Why exactly do you want it to start at 1? Either:
Start at 0 and adjust your indices as necessary; or
Start at 0 and just ignore index 0 (ie only use indices 1 and up).
A simple solution is to fill the zeroth item:
var map = [null, 'January', 'February', 'March'];
'First month : ' + map[1];
Semantically it would be better to use an object:
var map = {1:'January', 2:'February', 3:'March'};
'First month : ' + map[1];
Note these keys are not ints actually, object keys are always strings.
Also, we can't use dot notation for accessing. (MDN - Property Accessors)
I'd choose the first solution, which I think is less confusing.
Since this question also pops up for a Google search like "javascript start array at 1" I will give a different answer:
Arrays can be sliced. So you can get a sliced version of the Array like this:
var someArray = [0, 1, 2, 3];
someArray.slice(1);
[1, 2, 3]
someArray.slice(2, 4);
[2, 3]
Source: https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Array/slice
You could use delete to remove the first element like so:
let arr = ['a','b','c'];
delete arr[0];
console.log(arr[0]);
console.log(arr[1]);
Or just not define it at all:
let arr = [,'b','c'];
console.log(arr[0]);
console.log(arr[1]);
If you want to make sure that you always get the first truthy element regardless of the index and have access to ES6 you can use:
arr.find(Boolean)
The question asks "How to create an array in JavaScript whose indexing starts at 1". The accepted answer states "It isn't trivial. It's impossible."
This is true, and should be understood for good reason. However, you can create an array and omit setting the first element, in which case it will still exist (hence the accepted answer being correct) but it'll be marked as empty for you.
let usernames = ['bob', 'sally', 'frank']
let myArray = [];
let arrayIndex = 1;
usernames.map(username => {
myArray[arrayIndex] = username;
arrayIndex++;
})
console.log(myArray);
Array(4) [ <1 empty slot>, "bob", "sally", "frank" ]
1: "bob"
2: "sally"
3: "frank"
​length: 4
Notice that the length is "4".
console.log(myArray[0]);
undefined
Using this, there's a quirk in our favour whereby using Object.keys() on an array doesn't return empty (undefined) elements. So with the above array:
console.log(Object.keys(myArray).length);
3
Note: This is arguably a little hacky so use it with caution.
As zero of something rarely exists in our world, doing this might be useful where you are only going to access pre-defined indexes. An example would be if you have pages of a book. There isn't a page 0 as that makes no sense. And if you are always access a value directly, e.g.
const currentPage = pages[1];
Then this is fine in my opinion, as long as the code shows intent. Some will argue that ignoring a valid array index is futile, and I don't fully disagree. However, it's also futile and very annoying when I want to get page 35 of a book and the array index is 34. Meh!
When you loop your (dodgy) array with map it ignores the 0 index you didn't want:
myArray.map((value, index) => {
console.log(index);
console.log(value);
})
1
bob
2
sally
3
frank
For general use however, you should use index 0, so when you loop some data and spit things out you're not going to get caught out by the first one being empty.
Okay, according to #cletus you couldn't do that because it's a built-in javascript feature but you could go slightly different way if you still want that. You could write your own index-dependent functions of Array (like reduce, map, forEach) to start with 1. It's not a difficult task but still ask yourself: why do I need that?
Array.prototype.mapWithIndexOne = function(func) {
const initial = []
for (let i = 1; i < this.length + 1; i++) {
initial.push(func(this[i - 1], i))
}
return initial
}
const array = ['First', 'Second', 'Third', 'Fourth', 'Fifth']
console.log(array.mapWithIndexOne((element, index) => `${element}-${index}`))
// => ["First-1", "Second-2", "Third-3", "Fourth-4", "Fifth-5"]
Codepen: https://codepen.io/anon/pen/rvbNZR?editors=0012
Using Array.map
[,1,2,3].map((v, i) => ++i)
Just wanted to point out that an index in c ish languages is also the offset from the first element. This allows all sorts of offset math where you don't have to subtract 1 before doing the math, only to add the 1 back later.
if you want a "1" array because the indexes are mapped to other values, that's the case for an enumeration or a hash.
First add this function to your javascript codes:
var oneArray = function(theArray)
{
theArray.splice(0,0,null);
return theArray
}
Now use it like this:
var myArray= oneArray(['My', 'name', 'is', 'Ram']);
alert(myArray[1]); << this line show you: My
See live demo
Just prepend a null:
a = [1, 2, 3, 4]
a.unshift(null)
a[3] // 3
Simple, just make two changes to the classic Javascript for loop.
var Array = ['a', 'b', 'c'];
for (var i = 1; i <= Array.length; i++) {
//"i" starts at 1 and ends
//after it equals "length"
console.log(i);
}

Preventing a loop within a loop. How to reduce complexity

You have 2 arrays.
arrA is empty.
arrB is full of stuff (what it's full of doesnt matter, but assume it's huge).
When a user does a thing, an item is removed from arrB and that item is placed in arrA.
When a user does a different thing, it pulls items from arrA and puts it in arrB.
Is it possible to do this without having a loop within a loop?
Or to put it in computer science terminology:
Is it possible to do this with linear ( ϴ(n) ) time/space complexity?
Right now I have something that is at least ϴ(n*k)
(where n is the length of arrB, and k is the number of items passed to applyItems):
var arrA = [], arrB = [1, 2, 3, 4, 5, 6, 7, 8, 9, 0];
function addToArray(arrayToAddTo, item){
if(arrayToAddTo.indexOf(item) === -1){
arrayToAddTo.push(item);
}
}
function removeFromArray(arrayToRemoveFrom, item){
var i = arrayToRemoveFrom.length;
var temp = [];
while(i--){
if(arrayToRemoveFrom[i] !== item){
temp.push(arrayToRemoveFrom[i]);
}
}
return temp;
}
function applyItems(arrayOfItems){
var i = arrayOfItems.length;
while(i--){
var current = arrayOfItems[i]
addToArray(arrA, current);
arrB = removeFromArray(arrB, current);
}
}
applyItems([0, 5, 3]);
console.log(arrA);
console.log(arrB);
applyItems works, but is not efficient.
Is it possible to decrease the time/space complexity here?
Based on my comment:
You can use native tools that will be way faster than manually looping. removeFromArray can use indexOf to get the position of the one to remove and then uses splice to remove it. Also you can work with reference instead of recreating the array every time.
with some other optimizations...
var arrA = [], arrB = [1, 2, 3, 4, 5, 6, 7, 8, 9, 0];
function addToArray(item){
if(arrA.indexOf(item) === -1){
arrA.push(item);
}
}
function removeFromArray(item){
var index = arrB.indexOf(item);
if (index > -1) {
arrB.splice(index, 1);
}
}
function applyItems(arrayOfItems){
arrayOfItems.map(function(item) {
addToArray(item);
removeFromArray(item);
});
}
applyItems([0, 5, 3]);
console.log(arrA);
console.log(arrB);
Right now I have something that is at least ϴ(n*k)
You can make it O(n+k) by using an efficient lookup structure for arrayOfItems that does not require looping, but allows you to determine in O(1) whether an item should be swapped into the other array. With that, a single pass over arrB is enough.
Or if you sort your array and use binary search for the lookup, you will have O(log k * (n+k)). However if your array is finite and very small anyway, that hardly matters.
Also you should omit that indexOf test in addToArray. It seems to be established that no items are in both arrA and arrB (and your algorithm maintains that invariant), so you will not have to check for duplicates before pushing an item to the array.
Yes. Instead of making your own remove function, you can use splice().
So, instead of removeFromArray(arrB, current) you can just do arrB.splice(i, 1);. That will remove 1 element from index i.
You don't need to loop over every element to check if it matches the one you want - just use indexOf(). So you can do something like
var i = arrA.indexOf(item)

Remove objects from JS array upto a certain index

I have an array:
array = [S1,S2,S3,S4_a,S4_b,S5_a,S5_b,S5_c etc....]
How can I delete all the objects from the last object down to what ever index I give it ?
array.delte(last:S3)
So, I would like to to delete downto S3, so everything after it must be deleted
new_array = [S1,S2,S3]
It think you want splice:
array.splice(0, index);
var a = [1, 2, 3, 4, 5, 6];
a = a.splice(0, 3);
// a is now [1, 2, 3]
or, if you don't know the position of 3:
a = a.splice(0, a.indexOf(3) + 1);
Be aware though, that some browsers do not implement Array.indexOf so consider using a library such as jQuery or prototype.
Use javascript
array splice function , or array slice function. see : http://jsfiddle.net/
var origArray = new Array('a','b','c','d','e','f','g');
var myIndex = 4;
var origArray = origArray.slice(0,myIndex); // is now ['a','b','c','d']
Deleting all after index:
var index=3;
var arr1=['a','b','c','d','e','f','g'];
arr1.length=index; // now arr1 contains ['a','b','c']
Deleting all before index:
var index=3;
var arr1=['a','b','c','d','e','f','g'];
var arr2=arr1.slice(index); // now arr2 contains ['d','e','f','g']; arr1 remains unchanged

Getting the last value of an Array and showing it under X axis

var NewdateData[] = [1,2,3,4,5,6,7,8,9,1,2,1,23,45,56]
This NewdateData is dynamically filled from database depending upon the selection made from the user interface.
I am using this NewdateData for displaying under the X axis Charts.
The issue I am facing is that, the values are not taken till the end , I want to have the last value to have under the X axis Labels.
xaxis: {tickFormatter: function(n)
{
var k = Math.round(n);
return NewdateData[k];
}
I am using flotr.
You can get the last value of an array with:
NewdateData[NewdateData.length-1];
Very late to the party, but for posterity: in ES2015/ES6 you can use Array.prototype.slice. Doesn't mutate the array and a negative number gives you elements from the end of the array as a new array.
So to get the last element:
let arr = [1, 2, 3, 4, 5];
let last = arr.slice(-1); // last = 5
I don’t have enough points to comment on Radman’s post., but his solution is wrong.
let arr = [1, 2, 3, 4, 5]; let last = arr.slice(-1); // last = 5
Returns [5], not 5.
The slice() method returns a shallow copy of a portion of an array
into a new array object selected from begin to end (end not included).
The original array will not be modified.
The correct answer:
let arr = [1, 2, 3, 4, 5];
let last = arr.slice(-1)[0];
References: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/slice
Just do it with the map function.
this is the array what I want to pick the last item from it:-
const animals = ['Dodo', 'Tiger', 'Penguin', 'Dodo'];
loop over the array using map function to use the index parameter and compare it with animals array length:-
animals.map((animal, index) => animals.length -1 === index ? console.log("last item selected :)" + animal) : console.log("i'm not the last item"))
Now we are living with ES6 features
var arr = [1,2,3,4,5,6]
const [a, ...b] = arr.reverse();
console.log(a)
A simple and convenient way is to use Array.prototype.at()
function returnLast(arr) {
return arr.at(-1);
}
const cart = ['apple', 'banana', 'pear'];
const lastItem = returnLast(cart);
console.log(lastItem) //pear
or just
const lastItem = cart.at(-1)

How to create an array in JavaScript whose indexing starts at 1?

By default the indexing of every JavaScript array starts from 0. I want to create an array whose indexing starts from 1 instead.
I know, must be very trivial... Thanks for your help.
It isn't trivial. It's impossible. The best you could do is create an object using numeric properties starting at 1 but that's not the same thing.
Why exactly do you want it to start at 1? Either:
Start at 0 and adjust your indices as necessary; or
Start at 0 and just ignore index 0 (ie only use indices 1 and up).
A simple solution is to fill the zeroth item:
var map = [null, 'January', 'February', 'March'];
'First month : ' + map[1];
Semantically it would be better to use an object:
var map = {1:'January', 2:'February', 3:'March'};
'First month : ' + map[1];
Note these keys are not ints actually, object keys are always strings.
Also, we can't use dot notation for accessing. (MDN - Property Accessors)
I'd choose the first solution, which I think is less confusing.
Since this question also pops up for a Google search like "javascript start array at 1" I will give a different answer:
Arrays can be sliced. So you can get a sliced version of the Array like this:
var someArray = [0, 1, 2, 3];
someArray.slice(1);
[1, 2, 3]
someArray.slice(2, 4);
[2, 3]
Source: https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Array/slice
You could use delete to remove the first element like so:
let arr = ['a','b','c'];
delete arr[0];
console.log(arr[0]);
console.log(arr[1]);
Or just not define it at all:
let arr = [,'b','c'];
console.log(arr[0]);
console.log(arr[1]);
If you want to make sure that you always get the first truthy element regardless of the index and have access to ES6 you can use:
arr.find(Boolean)
The question asks "How to create an array in JavaScript whose indexing starts at 1". The accepted answer states "It isn't trivial. It's impossible."
This is true, and should be understood for good reason. However, you can create an array and omit setting the first element, in which case it will still exist (hence the accepted answer being correct) but it'll be marked as empty for you.
let usernames = ['bob', 'sally', 'frank']
let myArray = [];
let arrayIndex = 1;
usernames.map(username => {
myArray[arrayIndex] = username;
arrayIndex++;
})
console.log(myArray);
Array(4) [ <1 empty slot>, "bob", "sally", "frank" ]
1: "bob"
2: "sally"
3: "frank"
​length: 4
Notice that the length is "4".
console.log(myArray[0]);
undefined
Using this, there's a quirk in our favour whereby using Object.keys() on an array doesn't return empty (undefined) elements. So with the above array:
console.log(Object.keys(myArray).length);
3
Note: This is arguably a little hacky so use it with caution.
As zero of something rarely exists in our world, doing this might be useful where you are only going to access pre-defined indexes. An example would be if you have pages of a book. There isn't a page 0 as that makes no sense. And if you are always access a value directly, e.g.
const currentPage = pages[1];
Then this is fine in my opinion, as long as the code shows intent. Some will argue that ignoring a valid array index is futile, and I don't fully disagree. However, it's also futile and very annoying when I want to get page 35 of a book and the array index is 34. Meh!
When you loop your (dodgy) array with map it ignores the 0 index you didn't want:
myArray.map((value, index) => {
console.log(index);
console.log(value);
})
1
bob
2
sally
3
frank
For general use however, you should use index 0, so when you loop some data and spit things out you're not going to get caught out by the first one being empty.
Okay, according to #cletus you couldn't do that because it's a built-in javascript feature but you could go slightly different way if you still want that. You could write your own index-dependent functions of Array (like reduce, map, forEach) to start with 1. It's not a difficult task but still ask yourself: why do I need that?
Array.prototype.mapWithIndexOne = function(func) {
const initial = []
for (let i = 1; i < this.length + 1; i++) {
initial.push(func(this[i - 1], i))
}
return initial
}
const array = ['First', 'Second', 'Third', 'Fourth', 'Fifth']
console.log(array.mapWithIndexOne((element, index) => `${element}-${index}`))
// => ["First-1", "Second-2", "Third-3", "Fourth-4", "Fifth-5"]
Codepen: https://codepen.io/anon/pen/rvbNZR?editors=0012
Using Array.map
[,1,2,3].map((v, i) => ++i)
Just wanted to point out that an index in c ish languages is also the offset from the first element. This allows all sorts of offset math where you don't have to subtract 1 before doing the math, only to add the 1 back later.
if you want a "1" array because the indexes are mapped to other values, that's the case for an enumeration or a hash.
First add this function to your javascript codes:
var oneArray = function(theArray)
{
theArray.splice(0,0,null);
return theArray
}
Now use it like this:
var myArray= oneArray(['My', 'name', 'is', 'Ram']);
alert(myArray[1]); << this line show you: My
See live demo
Just prepend a null:
a = [1, 2, 3, 4]
a.unshift(null)
a[3] // 3
Simple, just make two changes to the classic Javascript for loop.
var Array = ['a', 'b', 'c'];
for (var i = 1; i <= Array.length; i++) {
//"i" starts at 1 and ends
//after it equals "length"
console.log(i);
}

Categories