Rotate an array from center position - javascript

I am trying to rotate an array from the center position. Say for example:
For an array [1,2,3,4,5] if I select 5 as the current element, the new array should be [3,4,5,1,2]. If I select 4, it should be [2,3,4,5,1]
I tried the below code and it works for some extent but it positions the selected at the beginning instead of center.
Any help with the approach will be really appreciated
var arr = [0,1,2,3,4];
function rot(arr, ind)
{
var narr = [];
var len = arr.length;
for(var i=0; i<arr.length; i++)
{
narr.push((i+ind<len?arr[i+ind]:arr[len-i-1]));
}
return narr;
}
console.log(rot(arr,0))

Try
let rot= (a,v,i=a.indexOf(v)) => a.map((x,j)=> a[(i+1+j+a.length/2)%a.length|0])
where n|0 cast float to integer. We use arrow function, indexOf and map
let arr=[1,2,3,4,5];
let rot=(a,v,i=a.indexOf(v))=>a.map((x,j)=>a[(i+1+j+a.length/2)%a.length|0]);
console.log( rot(arr,4) );
console.log( rot(arr,5) );

First, find how much you are going rotate the array (delta) then you splice as much items as its magnitude from the front if it is negative or the back if it is positive.
Put the spliced items on the opposite end.
function rot(arr, center) {
const index = arr.indexOf(center)
if (index === -1) {
throw new Error('')
}
if (arr.length % 2 === 0) {
throw new Error('')
}
const cIndex = Math.floor(arr.length/2)
const delta = cIndex - index
let narr = [...arr]
if (delta > 0) {
let temp = narr.splice(-delta)
narr = [...temp, ...narr]
}
else if (delta < 0) {
let temp = narr.splice(0, -delta)
narr = [...narr, ...temp]
}
return narr
}
let arr = [1,2,3,4,5]
console.log(rot(arr, 1))
console.log(rot(arr, 2))
console.log(rot(arr, 3))
console.log(rot(arr, 4))
console.log(rot(arr, 5))

this is basically the same as what #Mohammad posted, but instead of using ind as the index, you use arr.indexOf(ind) to get the relevant index.
I'd also add something to deal with the case you can't find the value...
let arrr = [1,2,3,4,5];
function rot(arr, ind) {
let narr = [...arr]; //copy and de-reference our array
let indexFound = narr.indexOf(ind); //find out where ind is
if(indexFound < 0 ) return narr; //ind was not found in your array
let len = Math.floor((narr.length/2) - indexFound); //find out how far your target is from the center
let doShift = (len < 0); //if len is negative, then we need elements from the beginning moved, otherwise move the elements off the end with pop()
len = Math.abs(len); //make sure len is always positive so our loop can run
for(var i=0; i<len; i++) {
if(doShift) narr.push(narr.shift());
else narr.unshift(narr.pop());
}
return narr;
}
console.log(rot(arrr,3));
console.log(rot(arrr,1));
console.log(rot(arrr,5));
Edit: modified to handle shifting from the end or beginning

Related

Trying to remove duplicate elements with the same values that are next to each other in an array (they have to preserve the original order)

So). This removes all duplicates. But I cann't figure out the logic for removing duplicates that are next to each other only.
For example:
input:('FFNNbbffnnNN');
output:[F, N, b, f, n, N];
var uniqueInOrder = function(iterable){
var newArr =[];
var len = iterable.length;
for(var i = 0; i < len ; i ++){
if( newArr.indexOf(iterable[i]) === -1){
newArr.push(iterable[i])
}
}
return newArr;
}
uniqueInOrder('ffssSnnsS');
Here I tried a little bit.. meh.. begging for tips. Thank you!
var uniqueInOrder = function(iterable){
var newArr =[];
var len = iterable.length;
var first = iterable[0];
for(var i = 0; i < len ; i ++){
if( newArr.indexOf(first) !== newArr.indexOf(first + 1){
newArr.push(iterable[i])
}
}
return newArr;
}
uniqueInOrder('ffssSnnsS');
Better to remove from backward to avoid miss splice when there are more than two duplicate elements after iteration took place:
var nums = [1,2,3,3,4,5,5,6,7,7,7,8];
for (i=nums.length-1; i > 0; i--) {
if(i <= nums.length && nums[i] === nums[i - 1]){
nums.splice(i,1);
}
}
console.log(nums);
Use Array.filter().
var nums = [1,2,3,3,4,5,5,6,7,7,8];
nums.forEach(function(num,index){
// Is the current index < the amount of itmes in the array
// and, if so, is the current item equal to the next item?
if(index < nums.length && num === nums[index + 1]){
nums.splice(index,1); // Remove the current item
}
});
console.log(nums);
I did it like this:
function uniqueInOrder(str) {
const letters = str.split('');
var lastLetter = null;
for (let [index,letter] of Object.entries(letters)) {
if (letter === lastLetter) {
letters[index] = null;
} else {
lastLetter = letter;
}
}
console.log(letters);
return letters.join('');
}
uniqueInOrder('ffssSnnsS');
I use split to turn it into an array. I keep track of the most recent previous letter. If the current letter matches, i null it in the array, otherwise i just update the lastLetter variable.

Longest decrease subsequence subarray in Javascript

I encountered this question:
Find longest decrease sequence in an array
So basically, if [3,1,4,3,2,1,2,3] is given, it will return [4,3,2,1] as the longest sequence within it. I was able to solve this question with O(n^2) time complexity but I feel like I can do O(n).
I know I am probably making a giant logic mistake but this is how I approach with 2 pointers method.
function findDecreaseSubArray(arr) {
let subList = [arr[0]];
// let maxLength= 0;
let left = 0;
for (let right = 1; right < arr.length; right++) {
// maxLength = (maxLength, windowEnd - windowStart + 1);
if (arr[left] > arr[right]) {
subList.push(arr[right]);
}else{
subList.shift();
left = right-1;
}
}
}
What I am trying to accomplish is moving left and right pointers if left element is larger than right, and if so, push both elements into sublist array.
My brain starts giving 404 error after this, so there are 2 subarrays that are decreasing, one of them is [3,1] and the other one is [4,3,2,1].
How could I track one subarray is larger than the other subarray? Or there is a better way to approach this solution?
Any hints, hands, code snippet would highly appreciated. (And sorry about my code snippet, I know it is shitty but I just wanted to display some of my thoughts on code)
You just have to iterate over the array once, but keep track of the start and length of the longest sequence as you progress through it:
var arr = [3,1,4,3,2,1,2,3];
function findDecreaseSubArray(arr) {
let startIndex = 0;
let length = 1;
let longestSequence = {
startIndex: 0,
length: 1
}
arr.forEach((element, index, arr) => {
if (index === 0) return;
if (element < arr[index -1]) {
length += 1;
} else {
length = 1;
startIndex = index;
}
if (length > longestSequence.length) {
longestSequence.length = length;
longestSequence.startIndex = startIndex;
}
})
return longestSequence;
}
console.log(findDecreaseSubArray(arr));
This approach supports VLAZ's comment and uses only the indices of the array.
function longestDecreasing(array) {
var longest,
start = 0,
i;
for (i = 0; i < array.length; i++) {
if (!i || array[i] < array[i - 1]) continue;
if (!longest || longest[1] - longest[0] < i - start) longest = [start, i];
start = i;
}
return array.slice(...longest && longest[1] - longest[0] > i - start
? longest
: [start, i]);
}
console.log(longestDecreasing([3, 1, 4, 3, 2, 1, 2, 3]))
It would probably be easier to iterate normally, from the first index to the end, while pushing sequential sequences to an array, which gets reset when a number greater than the last is found. When resetting, assign the resulting sequence array to a more permanent variable if it's longer than the array in that permanent variable:
const findDecreaseSubArray = (arr) => {
let longestSoFar = [];
let currentSequence = [];
const reset = (newItem) => {
if (currentSequence.length > longestSoFar.length) {
longestSoFar = currentSequence;
}
currentSequence = [newItem];
};
for (const item of arr) {
if (currentSequence.length && item > currentSequence[currentSequence.length - 1]) {
reset(item);
} else {
currentSequence.push(item);
}
}
reset();
return longestSoFar;
};
console.log(findDecreaseSubArray([3,1,4,3,2,1,2,3]));
Here is my code.
function getLongestDecreaseSequence(arr) {
if (
Object.prototype.toString.call(arr) !== "[object Array]" ||
arr.length == 0
) {
return arr;
}
let longestArr = [];
let tmpArr = [],
lastTmpIndex = -1;
arr.forEach((value, i) => {
if (arr[lastTmpIndex] < value) {
tmpArr = [];
}
// no matter what, I will put it in tmpArray
lastTmpIndex = i;
tmpArr.push(value);
if (longestArr.length < tmpArr.length) {
longestArr = tmpArr;
}
});
return longestArr;
}
console.log(getLongestDecreaseSequence([3, 1, 4, 3, 2, 1, 2, 3]));
This looks like a reducing job.
var a = [3,1,4,3,2,1,2,3],
r = a.reduce( function(r,e){
var l = r[r.length-1];
return l[l.length-1] > e ? ( l.push(e)
, r
)
: ( r.push([e])
, r
);
}
, [[]]
)
.reduce((p,c) => p.length > c.length ? p : c);
console.log(r);

Start a for loop on specific index and loop for array length

I'm trying to do a for loop on an array and be able to start that loop on a specific index and loop over the array x amount of times.
const array = ['c','d','e','f','g','a','b','c']
I want to loop 8 indexes starting at any index I wish. Example starting at array[4] (g) would return
'g','a','b','c','c','d','e','f'
This is what I've tried so far
const notes = ['c','d','e','f','g','a','b','c']
var res = []
for (var i = 4; i < notes.length; i++) {
res.push(notes[i])
}
console.log(res)
You can use modulo % operator.
const getArray = (array, index) => {
const result = [];
const length = array.length;
for (let i = 0; i < length; i++) {
result.push(array[(index + i) % length]);
}
return result;
};
Simple way.
var notes = ['c','d','e','f','g','a','b','c'];
function looparr(arr, start)
{
var res = [], start = start || 0;
for(var index = start, length=arr.length; index<length; index++)
{
res.push(arr[index]);
index == (arr.length-1) && (index=-1,length=start);
}
return res;
}
console.log(looparr(['c','d','e','f','g','a','b','c'], 0));
console.log(looparr(['c','d','e','f','g','a','b','c'], 2));
console.log(looparr(['c','d','e','f','g','a','b','c'], 4));
console.log(looparr(['c','d','e','f','g','a','b','c']));
Very simple solution below :)
While i < index, remove the first character from the array, store it in a variable and then add it back onto the end of the array.
let array = ['c','d','e','f','g','a','b','c'];
var index = 4;
for(var i = 0; i < index; i++) {
var letter1 = array.shift(i); // Remove from the start of the array
array.push(letter1); // Add the value to the end of the array
}
console.log(array);
Enjoy :)

Group items of two in one array

I am trying to push numbers in an array into another array in groups of two.
If I have an array [1,4,3,2]; it should return [[1,4],[3,2]];
var arrayPairSum = function(nums) {
var len = nums.length / 2;
var arr = [];
for(var i = 0; i < len; i ++) {
var newArr = [];
newArr.push(nums[i]);
newArr.push(nums[i + 1]);
arr.push(newArr);
}
console.log(arr); //this should give me [[1,4],[3,2]];
};
arrayPairSum([1,4,3,2]);
can anyone see what I need to do to achieve this? I cannot figure it out.
You can use reduce method to achieve this. reduce method accepts a callback method provided on every item in the array.
In the other words, this method applies a function against an accumulator and each element in the array (from left to right) to reduce it to a single value.
var array=[1,4,3,2,8];
var contor=array.reduce(function(contor,item,i){
if(i%2==0)
contor.push([array[i],array[i+1]].filter(Boolean));
return contor;
},[]);
console.log(contor);
If you really want to iterate over the array, may skip every second index, so i+=2 ( as satpal already pointed out) :
var arrayPairSum = function(nums) {
var len = nums.length - 1;//if nums.length is not even, it would crash as youre doing nums[i+1], so thats why -1
var arr = [];
for (var i = 0; i < len; i += 2) {
var newArr = [];
newArr.push(nums[i]);
newArr.push(nums[i + 1]);
arr.push(newArr);
}
console.log(arr); //this should give me [[1,4],[3,2]];
};
arrayPairSum([1, 4, 3, 2]);
The upper one crops away every non pair at the end. If you want a single [value] at the end, may go with
len=nums.length
And check later before pushing
if(i+1<nums.length) newArr.push(nums[i+1]);
You were pretty close. Simply change the length to nums.length and in the loop increment i by 2.
var arrayPairSum = function(nums) {
var len = nums.length - 1;
var arr = [];
for(var i = 0; i < len; i+=2) {
var newArr = [];
newArr.push(nums[i]);
newArr.push(nums[i + 1]);
arr.push(newArr);
}
console.log(arr); //this should give me [[1,4],[3,2]];
};
arrayPairSum([1,4,3,2]);

Alternate method to splice function in JavaScript

Hi i am working on LIME programming which is a subset of javascript.
i need to use javascript.splice to remove certain elements from my array, sad to say, LIME does not support splice function.
Any idea how do i create my own function to remove elements from an array?
Thanks for your time.
EDIT: Manage to create a simple function.
function removeElements(array, index)
{
var tempArray = new Array();
var counter = 0;
for(var i = 0; i < array.length; i++)
{
if(i != index)
{
tempArray[counter] = array[i];
counter++;
}
}
return tempArray;
}
Array.prototype.splice is fully defined in ECMA-262 §15.4.4.12, so use that as your spec and write one. e.g.
15.4.4.12 Array.prototype.splice (start, deleteCount [ , item1 [ ,item2 [ , … ] ] ] )
When the splice
method is called with two or more
arguments start, deleteCount and
(optionally) item1, item2, etc., the
deleteCount elements of the array
starting at array index start are
replaced by the arguments item1,
item2, etc. An Array object containing
the deleted elements (if any) is
returned. The following steps are
taken:...
You will probably have to create a new array, copy the members up to start from the old array, insert the new members, then copy from start + deleteCount to the end to the new array.
Edit
Here is an amended splice, the first I posted was incorrect. This one splices the array passed in and returns the removed members. It looks a bit long but I tried to keep it close to the spec and not assume support for any complex Array methods or even Math.max/min. It can be simplified quite a bit if they are.
If push isn't supported, it can be replaced fairly simply too.
function arraySplice(array, start, deleteCount) {
var result = [];
var removed = [];
var argsLen = arguments.length;
var arrLen = array.length;
var i, k;
// Follow spec more or less
start = parseInt(start, 10);
deleteCount = parseInt(deleteCount, 10);
// Deal with negative start per spec
// Don't assume support for Math.min/max
if (start < 0) {
start = arrLen + start;
start = (start > 0)? start : 0;
} else {
start = (start < arrLen)? start : arrLen;
}
// Deal with deleteCount per spec
if (deleteCount < 0) deleteCount = 0;
if (deleteCount > (arrLen - start)) {
deleteCount = arrLen - start;
}
// Copy members up to start
for (i = 0; i < start; i++) {
result[i] = array[i];
}
// Add new elements supplied as args
for (i = 3; i < argsLen; i++) {
result.push(arguments[i]);
}
// Copy removed items to removed array
for (i = start; i < start + deleteCount; i++) {
removed.push(array[i]);
}
// Add those after start + deleteCount
for (i = start + (deleteCount || 0); i < arrLen; i++) {
result.push(array[i]);
}
// Update original array
array.length = 0;
i = result.length;
while (i--) {
array[i] = result[i];
}
// Return array of removed elements
return removed;
}
If you don't care about order of the array and you're just looking for a function to perform splice, here's an example.
/**
* Time Complexity: O(count) aka: O(1)
*/
function mySplice(array, start, count) {
if (typeof count == 'undefined') count = 1
while (count--) {
var index2remove = start + count
array[index2remove] = array.pop()
}
return array
}
If you want to return the removed elements like the normal splice method does this will work:
/**
* Time Complexity: O(count) aka: O(1)
*/
function mySplice(array, index, count) {
if (typeof count == 'undefined') count = 1
var removed = []
while (count--) {
var index2remove = index + count
removed.push(array[index2remove])
array[index2remove] = array.pop()
}
// for (var i = index; i < index + count; i++) {
// removed.push(array[i])
// array[i] = array.pop()
// }
return removed
}
This modifies the original Array, and returns the items that were removed, just like the original.
Array.prototype.newSplice = function( start, toRemove, insert ) {
var remove = this.slice( start, start + toRemove );
var temp = this.slice(0,start).concat( insert, this.slice( start + toRemove ) );
this.length = 0;
this.push.apply( this, temp );
return remove;
};
Comparison test: http://jsfiddle.net/wxGDd/
var arr = [0,1,2,3,4,5,6,7,8];
var arr2 = [0,1,2,3,4,5,6,7,8];
console.log( arr.splice( 3, 2, 6 ) ); // [3, 4]
console.log( arr ); // [0, 1, 2, 6, 5, 6, 7, 8]
console.log( arr2.newSplice( 3, 2, 6 ) ); // [3, 4]
console.log( arr2 ); // [0, 1, 2, 6, 5, 6, 7, 8]
It could use a little extra detail work, but for the most part it takes care of it.
Here is a simple implement in case the Array.prototype.splice dispears
if (typeof Array.prototype.splice === 'undefined') {
Array.prototype.splice = function (index, howmany, elemes) {
howmany = typeof howmany === 'undefined' || this.length;
var elems = Array.prototype.slice.call(arguments, 2), newArr = this.slice(0, index), last = this.slice(index + howmany);
newArr = newArr.concat.apply(newArr, elems);
newArr = newArr.concat.apply(newArr, last);
return newArr;
}
}
Are there any other methods that are missing in LIME's Array implementation?
Assuming at least the most basic push() and indexOf() is available, there's several ways you could do it. How this is done would depend on whether this is destructive method or whether it should return a new array. Assuming the same input as the standard splice(index, howMany, element1, elementN) method:
Create a new array named new
push() indexes 0 to index onto the new array
Now stop at index and push() any new elements passed in. If LIME supports the standard arguments variable then you can loop through arguments with index > 2. Otherwise you'll need to pass in an array instead of a variable number of parameters.
After inserting the new objects, continue looping through the input array's elements, starting at index + howMany and going until input.length
I believe that should get you the results you're looking for.
I have used this below function as an alternative for splice()
array = mySplice(array,index,count);
above is the function call,
And this is my function mySplice()
function mySplice(array, index, count)
{
var newArray = [];
if( count > 0 )
{ count--;}
else
{ count++;}
for(i = 0; i <array.length; i++)
{
if(!((i <= index + count && i >= index) || (i <= index && i >= index + count)))
{
newArray.push(array[i])
}
}
return newArray;
}
I have done it very similar way using only one for loop
function removeElements(a,index,n){
// a=> Array , index=> index value from array to delete
// n=> number of elements you want to delete
let temp = []; // for storing deleted elements
let main_array = []; // for remaining elements which are not deleted
let k = 0;
for(let i=0;i<a.length;i++){
if((i===index) || ((index<i && i<n+index))){
temp[i]=a[i+1];
delete a[i];
}
if(a[i]!==undefined){
main_array[k] = a[i];
a[i] = main_array[k];
k++;
}
}
a=main_array;
return a;
}
a=[1,2,3,4,5];
console.log(removeElements(a,0,1));
follow link Jsfiddle
var a = [3, 2, 5, 6, 7];
var fromindex = 1
var toindex = 2;
for (var i = 0; i < a.length; i++) {
if (i >= fromindex + toindex || i < fromindex) {
console.log(a[i])
}
}
var a = [3, 2, 5, 6, 7];
var temp=[];
function splice(fromindex,toindex)
{
for (var i = 0; i < a.length; i++) {
if(i>=fromindex+toindex || i<fromindex)
{
temp.push(a[i])
}
}
return temp
}
console.log(splice(3,2))

Categories