Related
I'm learning Javascript and I'm wondering what the most elegant way to convert this: [1,8]
into this:[1,2,3,4,5,6,7,8]?
Thanks a lot!
const argarray = [1, 8]
const countToN = (array) => {
// init results array
let res = []
// start at the first value array[0] go *up to* the second array[1]
for (let i = array[0]; i <= array[1]; i++) {
res.push(i)
}
// return the result
return res
}
console.log(countToN([1, 10]))
This would accommodate what you're trying to do, but it's fairly brittle. You'd have to check that it's an array and that it has only 2 values. If you had other requirements, I could amend this to account for it.
Here's a solution without loops. Note that this only works with positive numbers. It supports arrays of any length, but will always base the result off of the first and last values.
const case1 = [1, 8];
const case2 = [5, 20];
const startToEnd = (array) => {
const last = array[array.length - 1];
const newArray = [...Array(last + 1).keys()];
return newArray.slice(array[0], last + 1);
};
console.log(startToEnd(case1));
console.log(startToEnd(case2));
Here's a solution that works for negative values as well:
const case1 = [-5, 30];
const case2 = [-20, -10];
const case3 = [9, 14];
const startToEndSolid = (array) => {
const length = array[array.length - 1] - array[0] + 1;
if (length < 0) throw new Error('Last value must be greater than the first value.');
return Array.from(Array(length)).map((_, i) => array[0] + i);
};
console.log(startToEndSolid(case1));
console.log(startToEndSolid(case2));
console.log(startToEndSolid(case3));
A simple for loop will do it. Here's an example that has error checking and allows you to range both backwards and forwards (ie [1, 8], and also [1, -8]).
function range(arr) {
// Check if the argument (if there is one) is
// an array, and if it's an array it has a length of
// of two. If not return an error message.
if (!Array.isArray(arr) || arr.length !== 2) {
return 'Not possible';
}
// Deconstruct the first and last elements
// from the array
const [ first, last ] = arr;
// Create a new array to capture the range
const out = [];
// If the last integer is greater than the first
// integer walk the loop forwards
if (last > first) {
for (let i = first; i <= last; i++) {
out.push(i);
}
// Otherwise walk the loop backwards
} else {
for (let i = first; i >= last; i--) {
out.push(i);
}
}
// Finally return the array
return out;
}
console.log(range([1, 8]));
console.log(range('18'));
console.log(range());
console.log(range([1]));
console.log(range([-3, 6]));
console.log(range([9, 16, 23]));
console.log(range([4, -4]));
console.log(range([1, -8, 12]));
console.log(range(null));
console.log(range(undefined));
console.log(range([4, 4]));
Additional documentation
Destructuring assignment
Use Array#map as follows:
const input = [1,8],
output = [...Array(input[1] - input[0] + 1)]
.map((_,i) => input[0] + i);
console.log( output );
There is an array:
let arr=[
[1000,800,1,"true"],
[1500,0,2,"false"],
[1600,0,3,"true"],
[2500,300,4,"false"]
]
I want the result:
let arr_result=[
[1000,800,1,"true"],
[500,0,2,"false"],
[100,0,3,"true"],
[900,300,4,"false"]
]
That is, let the latter sub-array element[0] subtract the previous sub-array element[0].
I need to do it in javascript.
How to do it?
You can use map method and then simply use index param to get previous element by using array[index - 1] and then first element of that sub array.
let arr = [
[1000, 800, 1, "true"],
[1500, 0, 2, "false"],
[1600, 0, 3, "true"],
[2500, 300, 4, "false"]
]
const result = arr.map(([e, ...rest], i) => (
[i ? e - arr[i - 1][0] : e, ...rest]
))
console.log(result)
Define a variable prev to update it with the value from the previous item. Then, iterate over the array using Array#map to update the first element and prev as follows:
const arr = [ [1000,800,1,"true"], [1500,0,2,"false"], [1600,0,3,"true"], [2500,300,4,"false"] ];
let prev;
const res = arr.map(e => {
const val = e[0] - (prev || 0);
prev = e[0];
e[0] = val;
return e;
});
console.log(res);
One way to do it is to assign the current array to the result array then loop over current array backwards and subtract the value then put it in result array
let arr=[
[1000,800,1,"true"],
[1500,0,2,"false"],
[1600,0,3,"true"],
[2500,300,4,"false"]
]
var res = arr;
for(var i = arr.length -1; i > 0; i--){
res[i][0] = arr[i][0] - arr[i - 1][0];
}
console.log(res);
[
[1000,800,1,"true"],
[500,0,2,"false"],
[100,0,3,"true"],
[900,300,4,"false"]
]
I have an array that I created using Array(...) and Array.prototype.map, like this:
var array_name = Array(255).map(function(undef, i) {
return i + 1;
});
The values of this array are:
[1, 2, 3, ..., 253, 254, 255]
This is an array that won't get modified, so the first value of this array will always be 1 and the last value of this array will always be 255.
I already know the index of each value is {value} - 1, so 200 would be 199, 199 would be 198, so on and so forth.
Let's say I want 255's opposite value, which would be 0, I could get that using array_name[0], but what if I wanted 200's opposite value, how would I know what the opposite index of 199 is so I could get it's value?
Do:
opposite_index = arr.length - index - 1
For example:
a = [1,2,3,4,5,6,7,8,9,10]
index = 3
a[index]
4
It's opposite is 7 so:
opposite_index = a.length - index - 1
a[opposite_index]
7
With reverse as per #Maheer Ali suggestion:
a.reverse()[index]
7
Your Array(255).map() create undefined array value.So do with Array#from length object.And pass your value.get index of the value and match with reverse array you get opposite value
let check = (val) => {
var array_name = Array.from({length:255},(a,b)=>b+1);
var nor_ind = array_name.indexOf(val);
var re_in = array_name.reverse(array_name).indexOf(val)
return ({nor_val:val,nor_ind:nor_ind,opp_val:re_in})
}
console.log(check(254))
First of all the code you provided doesn't create array [1,2,3...255]. It will create it will 255 empty items first you need to fill().
var arr = Array(255).fill().map((a,i) => i+1);
//Create an array which will have revese items.
let revarr= arr.reverse()
console.log(revarr[0]) //255
console.log(revarr[254]) // 1
If you don't want to create a reverse arr. You can create a function
var arr = Array(255).fill().map((a,i) => i+1);
const opp = (arr,num) => arr[arr.length - num - 1];
console.log(opp(arr,0));
console.log(opp(arr,254));
First, you gotta understand that there is weird behavior concerning Array(n).map(f) (it won't create the array you're expecting), see this answer for explanation, second, do this to get the opposite values:
/* fill it first with .fill(), see the question I linked for more explanation */
var array = Array(255).fill(undefined).map(function(undef, i) {
return i + 1;
});
function opposite(array, n) {
return array[array.length - n];
}
console.log(opposite(array, 255));
console.log(opposite(array, 200));
console.log(opposite(array, 199));
console.log(opposite(array, 1));
Notice that length - n is used instead of length - n - 1, because we're dealing with values from 1 to n, not from 0 to n - 1.
Subtract the index from (length-1) -> max index of the array
let arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
function findOpp(index, length) {
maxIndex = length - 1;
if (index <= maxIndex && index >= 0) {
return maxIndex - index;
} else {
return 'You have enter a wrong index';
}
}
console.log(findOpp(-1, 10));
console.log(findOpp(0, 10));
console.log(findOpp(1, 10));
console.log(findOpp(2, 10));
console.log(findOpp(4, 10));
console.log(findOpp(5, 10));
console.log(findOpp(6, 10));
console.log(findOpp(7, 10));
console.log(findOpp(8, 10));
console.log(findOpp(9, 10));
console.log(findOpp(10, 10));
Using Maheer Ali's suggestion I managed to get the desired result by reversing the array and using indexOf to get the index of that number:
var numbers = Array(255).map(function(v, i) {
return i + 1;
});
var opposite_brightness = numbers.reverse()[numbers.indexOf(brightness)];
I have very long array containing numbers. I need to remove trailing zeros from that array.
if my array will look like this:
var arr = [1,2,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0];
I want to remove everything except [1, 2, 0, 1, 0, 1].
I have created function that is doing what is expected, but I'm wondering if there is a build in function I could use.
var arr = [1,2,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0];
for(i=arr.length-1;i>=0;i--)
{
if(arr[i]==0)
{
arr.pop();
} else {
break;
}
}
console.log(arr);
Can this be done better/faster?
Assuming:
var arr = [1,2,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0];
You can use this shorter code:
while(arr[arr.length-1] === 0){ // While the last element is a 0,
arr.pop(); // Remove that last element
}
Result:
arr == [1,2,0,1,0,1]
var arr = [1,2,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0];
var copy = arr.slice(0);
var len = Number(copy.reverse().join('')).toString().length;
arr.length = len;
arr -> [1, 2, 0, 1, 0, 1]
how it works
copy.reverse().join('') becomes "00000000000000000101021"
when you convert a numerical string to number all the preceding zeroes are kicked off
var len = Number(copy.reverse().join('')) becomes 101021
now by just counting the number i know from where i have to remove the trailing zeroes and the fastest way to delete traling elements is by resetting the length of the array.
arr.length = len;
DEMO
const arr = [0,0,0,1,2,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0];
My solution is:
arr.join('').replace(/0+$/g,'').split('').map(Number);
It will remove trailing zeros in the given array.
Result is [0,0,0,1,2,0,1,0,1];
If you also needed to remove leading zeros, you can adjust the regex like this:
arr.join('').replace(/^0+|0+$/g,'').split('').map(Number);
Now It will remove not only trailing zeros, but leading zeros too.
Result is [1,2,0,1,0,1];
Accepted answer is perfectly well. Just for fun here is a reducing approach.
var a = [1,0,1,0,1,0,1,2,3,4,5,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0];
f = a => { var b = true;
return a.reduceRight((r,n,i) => ( b ? n && ( b = false
, r[i] = n
)
: r[i] = n
, r
)
, []
);
};
console.log(f(a));
Here's a one-liner representing javascript at both its best and worst at the same time.
var arr = [1,2,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
arr.slice(0,arr.reduceRight(([d,l],c) => [d||c,l-!(d||c)], [false,arr.length])[1])
Output:
[ 1, 2, 0, 1, 0, 1 ]
A simpler immutable approach using reduceRight
const arr = [1,2,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0];
const prunedArray = arr.reduceRight((acc, item) => {
if(item === 0 && acc.length === 0) {
return acc;
}
return acc.concat(item);
}, []);
console.log(prunedArray); // [1, 0, 1, 0, 2, 1]
I have this javascript:
function padded_array(k, value){
var a = [];
a[k] = value;
return a;
}
padded_array(3, "hello"); //=> [undefined, undefined, undefined, 'hello']
Is it possible to shorten the code in the function body?
for all the googlers coming here - you're probably looking for this:
var pad_array = function(arr,len,fill) {
return arr.concat(Array(len).fill(fill)).slice(0,len);
}
From 2020 & 2021 : straight forward options
Let assume that is your Array
const yourArray = [1,2]
If you just want to loop 4 times (maybe for react jsx )
Array.from({length:4}) //[undefined,undefined,undefined,undefined]
Array(4).fill()//[undefined,undefined,undefined,undefined]
If you want to loop yourArray 4 times, but to start with values you already have
// unmutation option
Array.from({...yourArray, length:4}) //[1,2,undefined,undefined]
// unmutation option, but need some calcualtion
[...yourArray , ...Array(2) ] //[1,2,undefined,undefined]
[...Array(2), ...yourArray ] //[undefined,undefined,1,2]
// loop on your array several times
Array(3).fill(yourArray).flat() // [1, 2, 1, 2, 1, 2]
// mutation the original array.
yourArray.length = 4;
Array.from(yourArray) //[1,2,undefined,undefined]
If You actually want an Array with full of values. ex. with increment numbers.
Remap it
// unmutation option
Array.from({...yourArray,length:4}, (v,i) => v ?? i+1 )
// [1,'2',3, 4]
// Or, mutation the original array. and fill with "x"
array.yourArray.length = 4;
Array.from(yourArray, (v) => v ?? 'x')
// [1,'2','x','x']
If you want to exclude the 'hello', you can use
new Array(count);
to create padded Arrays.
Edit: Maybe like this ?
new Array(5).concat("hello")
Another solution using spread operator:
padArray = (length, value) => [...Array(length).fill(), value];
And the usage is the same as you mentioned:
padded_array(3, "hello"); //=> [undefined, undefined, undefined, 'hello']
For padding at the start:
function padArrayStart(arr, len, padding){
return Array(len - arr.length).fill(padding).concat(arr);
}
Demo:
function padArrayStart(arr, len, padding){
return Array(len - arr.length).fill(padding).concat(arr);
}
console.log(...padArrayStart([1,2,3], 5, 0));//0 0 1 2 3
console.log(...padArrayStart([4,5,6], 3, 0));//4 5 6
For padding at the end:
function padArrayEnd(arr, len, padding){
return arr.concat(Array(len - arr.length).fill(padding));
}
Demo:
function padArrayEnd(arr, len, padding){
return arr.concat(Array(len - arr.length).fill(padding));
}
console.log(...padArrayEnd(['a','b','c'], 10, 'z'));//a b c z z z z z z z
console.log(...padArrayEnd([0, 'a', 'd'], 6, -1));//0 a d -1 -1 -1
Not in standard ES5 or predecessor. Surely you can do something like $.extend([], {"3": "hello"}) in jQuery; you can even do
Object.create(Array.prototype, {"3": {value: "hello"} });
in bare ES5, but it is hack, I would not consider this a solution (if it is ok with you, you can adopt it).
You can use that if your JS doesn't support Array.prototype.fill() (ex. Google Apps Script) and you can't use the code from the first answer:
function array_pad(array, length, filler)
{
if(array.length < length)// [10.02.20] Fixed error that Dimitry K noticed
while(true)
if(array.push(filler) >= length)
break;
return array;
}
I know this is an old(er) question but wanted to add my 2 cents if someone stumbles here (like i initially did).
Anyway, heres my take with Array.from
const padded_array = (k, value) => Array.from({ length: k }).concat(value)
console.log(padded_array(3, "hello"));
Also you could do it with something like this:
const padded = (arr, pad, val) => {
arr[pad] = val
return arr
}
console.log(padded([],3,'hello'))
// push is faster than concat
// mutate array in place + return array
const pad_right = (a, l, f) =>
!Array.from({length: l - a.length})
.map(_ => a.push(f)) || a;
const a = [1, 2];
pad_right(a, 4, 'x');
// -> [ 1, 2, 'x', 'x' ]
a;
// -> [ 1, 2, 'x', 'x' ]
function leftPad(array, desiredLength, padding) {
array.unshift(...Array(desiredLength - array.length).fill(padding));
}
function rightPad(array, desiredLength, padding) {
array.push(...Array(desiredLength - array.length).fill(padding));
}
const myHello = ['hello'];
leftPad(myHello, 3, undefined);
// [undefined, undefined, 'hello']
const myHello2 = ['hello2'];
rightPad(myHello, 3, 0);
// ['hello2', 0, 0];