Get the N elements from array based on the position - javascript

I want a function that returns the sub array which takes a position & the no. of elements I want. I think there may be some algorithm to find the pivot point or something & from that I can get the sub array, but I totally forgot it.
Example: a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
I want 6 elements
if position = 0, then I want [1, 2, 3, 4, 5, 6]
if position = 1, then [1, 2, 3, 4, 5, 6]
if position = 2, then [1, 2, 3, 4, 5, 6]
if position = 3, then [1, 2, 3, 4, 5, 6]
if position = 4, then [2, 3, 4, 5, 6, 7]
if position = 5, then [3, 4, 5, 6, 7, 8]
if position = 6, then [4, 5, 6, 7, 8, 9]
if position = 7, then [5, 6, 7, 8, 9, 10]
if position = 8, then [5, 6, 7, 8, 9, 10]
if position = 9, then [5, 6, 7, 8, 9, 10]
simply get the middle of N elements based on the position I pass.
I can write up my own loop which will contain multiple if-else conditions to get it done. But I feel there may be some easy way to do it.
I didnt include my incomplete code snippet because I strongly feel there must be some algorithm to do this.

What you want is : Array.prototype.slice(...)
It's neatly documented here : https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/slice
var n = 6;
var start = Math.max(0, Math.min(Math.floor(position-n/2), a.length-n));
return a.slice(start, start+n);

Simple way:
var a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
function getSubArray(idx, _length, _array) {
return _array.slice(idx, idx + _length);
}
var subArray = getSubArray(3, 6, a);

You could use an offset for the postion and get the the start value first for slicing.
var a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
n = 6,
i,
start;
for (i = 1; i < 12; i++) {
start = Math.max(Math.min(i - n / 2, a.length - n), 0);
console.log(i, ': ', a.slice(start, start + n).join());
}

Your only need is to check if you are not gonna check a pos that doesn't exist. Like :
var a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
var n = 6; // Number of result you want
var x = 8; // Pos you want
// If you gonna exceed your length, we got only the n last element
if((x+(n/2)) > a.length) {
console.log(a.slice(a.length-n));
// Otherwise, if under 0, we got the n first
} else
if((x-(n/2)) < 0) { console.log(a.slice(0,n) );
// Default case
} else {
console.log(a.slice((x-(n/2)),(x+(n/2))));
}
This is not the smartest way, but he can give you some hint. I used the slice as other mentionned to avoid a lot of if, but you should do GENERIC test.

Something like this :
a = [1,2,3,4,5,6,7,8,9,10];
n = 6;
function split(position) {
var start = Math.min(Math.max(position - Math.floor(n/2), 0), a.length - n);
var stop = Math.min(start+n, a.length);
return a.slice(start, stop);
}

No need for the Math object at all. You may simply do as follows;
function getArr(a,n,d){
n = n - 4 < 0 ? 0
: a.length - d > n - 4 ? n - 3
: a.length - d;
return a.slice(n,n + d);
}
var arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
diff = 6;
for (var i = 0; i < 10; i ++) console.log(JSON.stringify(getArr(arr,i,diff)));

no need of if-else you can use arr[position] to arr[8]. have you got
function getArr(arr,position,requiredNumbers){
return arr.slice(position, position+requiredNumbers);
}

Related

multiplying certain elements of an array javascript

var valid1=[4, 5, 3, 9, 6, 7, 7, 9, 0, 8, 0, 1, 6, 8, 0, 8]
function validateCred(array) {
let doubleArray =0
for(i=array.length-2; i >= 0; i-=2) {
doubleArray= array[i]*2
}
console.log(doubleArray);
}
validateCred(valid1) //prints 8 I want it to print entire loop
Im trying to code luhn Algorithm and this is the first step of doubling every second number from the back, i want my result to equal doubleArray however when i try print it only 8 prints
you have only 8 prints because you have step i-2. Also, see comments in code about reversing an array
const valid1 = [4, 5, 3, 9, 6, 7, 7, 9, 0, 8, 0, 1, 6, 8, 0, 8];
function validateCred(array) {
let doubleArray = [];
// we should move through all iterations that is why step i-=1
for(let i = array.length-1; i >= 0; i -= 1) {
// moving from the end of the array we will get reversed copy if using method push()
// that is why changed to unshift()
doubleArray.unshift((array.length - 1 - i) % 2 == 0 ? array[i] * 2 : array[i]);
// array.length - 1 - i - using because we need to move from right in case length not odd
}
console.log(doubleArray);
}
// ES6+ syntax version version
function esValidateCred1(array) {
const doubleArray = array.reverse().map((i, ind) => ind % 2 === 0 ? i*2 : i).reverse();
console.log(doubleArray);;
}
validateCred(valid1);
esValidateCred1(valid1);
You can refer the code below to get the desired output i.e. the an array with doubled value starting from back.
var valid1=[4, 5, 3, 9, 6, 7, 7, 9, 0, 8, 0, 1, 6, 8, 0, 8]
function validateCred(array) {
let doubleArray = [];
for(i=array.length-2; i >= 0; i-=2) {
doubleArray.push(array[i] * 2)
}
return(doubleArray);
}
console.log(validateCred(valid1))
the easiest way is to use .map() method for array
var valid1=[4, 5, 3, 9, 6, 7, 7, 9, 0, 8, 0, 1, 6, 8, 0, 8]
function validateCred(array) {
return array.map(item => item*2);
}
console.log( validateCred(valid1) ) //prints array doubled elements

How to sort an array starting from the middle?

Considering, I have an array like this [..., n-2, n-1, n, n+1, n+2, ...]. I would like to sort it in this way [n, n+1, n-1, n+2, n-2,...] with n equals to the middle of my array.
For example:
Input:
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
Output:
[5, 6, 4, 7, 3, 8, 2, 9, 1, 0]
let arrayNotSorted = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
let positionMiddleArray = Math.trunc(arrayNotSorted.length / 2);
let arraySorted = [arrayNotSorted[positionMiddleArray]];
for(let i=1; i <= positionMiddleArray; i++){
if(arrayNotSorted[positionMiddleArray + i] !== undefined){
arraySorted.push(arrayNotSorted[positionMiddleArray + i]);
}
if(arrayNotSorted[positionMiddleArray - i] !== undefined){
arraySorted.push(arrayNotSorted[positionMiddleArray - i]);
}
}
console.log('Not_Sorted', arrayNotSorted);
console.log('Sorted', arraySorted);
What I have done works properly, but I would like to know if there is a better way or a more efficient way to do so ?
You could take a pivot value 5 and sort by the absolute delta of the value and the pivot values an sort descending for same deltas.
var array = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9],
pivot = 5;
array.sort((a, b) => Math.abs(a - pivot) - Math.abs(b - pivot) || b - a);
console.log(...array); // 5 6 4 7 3 8 2 9 1 0
You can do that in following steps:
Create an empty array for result.
Start the loop. Initialize i to the half of the length.
Loop backwards means decrease i by 1 each loop.
push() the element at current index to the result array first and the other corresponding value to the array.
function sortFromMid(arr){
let res = [];
for(let i = Math.ceil(arr.length/2);i>=0;i--){
res.push(arr[i]);
res.push(arr[arr.length - i + 1])
}
return res.filter(x => x !== undefined);
}
console.log(sortFromMid([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]))
[5, 6, 4, 7, 3, 8, 2, 9, 1, 0]

how to check if 2 rows are symmetrical?

i have 2 rows that i need to check in java script if they are symmetrical
row 1 [2, 7, 9, 9, 7, 2] row 2 [5 7 3 3 7 5] how would you do it ?
var r = [[5, 7, 3, 3, 7, 5], [2, 7, 9, 9, 7, 2]];
function isSymmetric(r) {
// convert to object
var rel = {}
for (var i = 0; i < r.length; i++) {
if (!(r[i][0] in rel)) rel[r[i][0]] = {};
rel[r[i][0]][r[i][1]] = true;
}
// Test to see if opposite relation is in object
for (var a in rel) {
for (var b in rel[a]) {
if (!rel[b] || !rel[b][a]) return false;
}
}
return true;
}
console.log(isSymmetric(r));
You could do something like this:
let isSymmetric = arr => {
for(var i=0; i < arr.length; i++) {
if(arr[i] !== arr[arr.length - (i+1)])
return false
}
return true
}
console.log(isSymmetric([5, 7, 3, 3, 7, 5]))
console.log(isSymmetric([1, 7, 9, 9, 7, 2]))
The idea is to loop through the array and for each index compare with its "sibling" from the right side. If one is not the same them return false.
You can start from 0th index and compare the value with its symmetric pair (length - 1 - i), and if they are not same then return false. You should stop at the middle length / 2:
let values = [
[5, 7, 3, 3, 7, 5],
[2, 7, 9, 1, 9, 7, 2],
[5, 7, 3, 3, 7, 1]
];
function isSymmetric(arr) {
for (let i = 0; i < arr.length / 2; i++) {
if (arr[i] !== arr[arr.length - 1 - i]) {
return false;
}
}
return true;
}
values.forEach(v =>
console.log(isSymmetric(v))
);
Use lodash.
var row = [2, 7, 9, 9, 7, 2];
var halves = _.chunk(row, _.ceil(row.length / 2));
var result = _.isEqual(halves[0], _.reverse(halves[1]));

javascript odd and even separation in an array of numbers

i wants to separate an array with two groups (odd and even) sequentially. but when i try this:
var arr = [1, 2, 3, 4, 5, 6, 7, 8, 9];
for (var i = 0; i < arr.length; i++) {
if (arr[i]%2 == 0) {
arr.push(arr.splice(i, 1)[0]);
}
}
console.log(arr);
console.log(arr);
// [1, 3, 5, 7, 9, 4, 8, 6, 2]
why 4,8,6,2 instead of 2,4,6,8?
Because you move every found even value to the end of the array:
0: 1 2 3 4 5 6 7 8 9
^-------------v
1: 1 3 4 5 6 7 8 9 2 3 is not checked, because of the incremented index after splicing
^-----------v
2: 1 3 5 6 7 8 9 2 4 5 is not checked
^---------v
3: 1 3 5 7 8 9 2 4 6 7 is not checked
^-------v
4: 1 3 5 7 9 2 4 6 8 9 is not checked
^-----v
5: 1 3 5 7 9 4 6 8 2
^---v
6: 1 3 5 7 9 4 8 2 6
^-v
7: 1 3 5 7 9 4 8 6 2
|
8: 1 3 5 7 9 4 8 6 2
But, you do not check the value after the found even value, like the value 3 in line zero, because it is never checked and stays at this place, as well as other actually uneven values. You could try the whole again with all even at the beginning of the array, like
var array = [2, 4, 6, 8, 1, 3, 5, 7, 9];
for (var i = 0; i < array.length; i++) {
if (array[i] % 2 === 0) {
array.push(array.splice(i, 1)[0]);
console.log(i + ': ' + array.join(' '));
}
}
console.log(array);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Solution
You could use a length for checking and reduce the length for every found even value. In this case, the index stays at the value, because at the index is now the next element for checking.
var array = [1, 2, 3, 4, 5, 6, 7, 8, 9],
i = 0,
l = array.length;
while (i < l) {
if (array[i] % 2 === 0) {
array.push(array.splice(i, 1)[0]);
l--;
continue;
}
i++;
}
console.log(array);
Or just sort.
By moving odd values to top and then sort by value.
var array = [1, 2, 3, 4, 5, 6, 7, 8, 9];
array.sort((a, b) => b % 2 - a % 2 || a - b);
console.log(array);
The way you do it is so complicated. You can simply achieve that with array.prototype.filter and array.prototype.concat:
var arr = [1, 2, 3, 4, 5, 6, 7, 8, 9];
arr = arr.filter(e => e%2).concat(arr.filter(e => e%2 === 0));
console.log(arr);
why 4,8,6,2 instead of 2,4,6,8?
Basically when half of the iterations are done, it is re-processing the pushed items.
You need to change the for-loop as
for (var i = 0; i < arr.length/2; i++) {
if (arr[i]%2 == 0) {
arr.push(arr.splice(i, 1)[0]);
}
}
Demo
var arr = [1, 2, 3, 4, 5, 6, 7, 8, 9];
for (var i = 0; i < arr.length / 2; i++) {
if (arr[i] % 2 == 0) {
arr.push(arr.splice(i, 1)[0]);
}
}
console.log(arr);
Edit
And if the order of items is not always sorted, then you apart from sorting it first, you can reduce the length variable.
var arr = [1, 2, 4, 3, 5, 6, 7, 8, 9];
var length = arr.length;
for (var i = 0; i < length; i++) {
console.log(i,arr[i]);
if (arr[i] % 2 == 0) {
arr.push(arr.splice(i, 1)[0]);
console.log("result ", arr)
length--;
i--;
}
}
console.log(arr)
why 4,8,6,2 instead of 2,4,6,8?
it is because you are modifying the same Array which you are looping through.
to understand better, lets loop through your code
after
1st Loop: array: [1, 2, 3, 4, 5, 6, 7, 8, 9];
2nd loop: array: [1, 3, 4, 5, 6, 7, 8, 9, 2];
3rd loop: array: [1, 3, 5, 6, 7, 8, 9, 2, 4];
4th loop: array: [1, 3, 5, 7, 8, 9, 2, 4, 6];
5th loop: array: [1, 3, 5, 7, 9, 2, 4, 6, 8];
6th loop: array: [1, 3, 5, 7, 9, 4, 6, 8, 2];
7th loop: array: [1, 3, 5, 7, 9, 4, 8, 2, 6];
8th loop: array: [1, 3, 5, 7, 9, 4, 8, 6, 2];
9th loop: array: [1, 3, 5, 7, 9, 4, 8, 6, 2];
to separate out odd/even in an array,
we will have to filter out odd and even separately and push evenArray in the end of oddArray(filtered Array)
var input = [1, 2, 3, 4, 5, 6, 7, 8, 9];
input = input.sort((a, b)=> a-b); //to sort array if not sorted already
var evenArr = [];
input = input.filter(item => {
if (item % 2 != 0)
return true
else {
evenArr.push(item);
return false;
}
})
Array.prototype.push.apply(input, evenArr);
console.log(input);
I believe this can be covered by lodash _.partition:
var arr = [1, 2, 3, 4, 5, 6, 7, 8, 9];
var [odds, evens] = _.partition(arr, function(n) {
return n % 2;
});
console.log(_.concat(odds, evens));
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.min.js"></script>
Or even shorter:
_.groupBy(arr, function(n) {return (n % 2) ? 'odd' : 'even';})

How to create a proper sum function?

I'm trying to create a sum function. When I run it through two different arrays (with same values), it's giving me different results. I can't really tell where I did wrong. It seems when I'm generating the array using the 'range' function, it's looping twice.
var myArr = [];
var tempArr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
function range(start, end) {
for (i = start; i <= end; i++) {
myArr.push(start);
start = start + 1;
}
return myArr;
}
function sum(arr) {
var sumArr = 0;
for (i = 0; i < arr.length; i++) {
sumArr = sumArr + arr[i];
//console.log(sumArr);
}
return sumArr;
}
console.log(range(1, 10)); //[ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ]
console.log(tempArr); //[ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ]
console.log(sum(range(1, 10))); //110
console.log(sum(tempArr)); //55
Any help would be appreciated. Thanks!
The reason is that var myArr = []; was a global variable. So pushed elements in the first console attempt will be there until they are cleared. You can use local variable in the function instead.
var tempArr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
function range(start, end) {
var myArr = [];
for (i = start; i <= end; i++) {
myArr.push(start);
start = start + 1;
}
return myArr;
}
function sum(arr) {
var sumArr = 0;
for (i = 0; i < arr.length; i++) {
sumArr = sumArr + arr[i];
//console.log(sumArr);
}
return sumArr;
}
console.log(range(1, 10)); //[ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ]
console.log(tempArr); //[ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ]
console.log(sum(range(1, 10))); //55
console.log(sum(tempArr)); //55
Using lodash :
You can use ._sum function.
var tempArr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
sum = _.sum(tempArr)
Don't forget to add the library if you want to use it.
<script src="https://cdn.jsdelivr.net/lodash/4.5.1/lodash.min.js"></script>
Demo

Categories