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"]
]
Related
Given the array below, how I can return the element whose first index contains the highest number:
let ar = [[1,24], [2, 6]]
I've tried many proposed solutions, but they return the number itself, while it should be, in the case above [2,6]
One of the solutions I've tried is, but it returns 24, 6:
var maxRow = arr.map(function(row){ return Math.max.apply(Math, row); });
To do what you require you can use reduce() to compare the values of the first item in each child array and return the one with the highest value:
let ar = [[1,24], [2, 6]]
let result = ar.reduce((acc, cur) => acc[0] < cur[0] ? cur : acc);
console.log(result);
One way is using a reduce. Try like this:
const ar = [
[1,24],
[2, 6],
];
const biggest = ar.reduce(
(acc, cur) => cur[0] > (acc?.[0] || 0) ? cur : acc,
[],
);
console.log(biggest);
I want to perform an operation involving the current and the next array element.
For example, add current element with the next:
let arr = [0,1,2,3,4,5];
let newarr = arr.map((a,b) => a+b); //here, a and b are treated as the same element
expecting it to yield a new array of sums of current and next array element:
[0+1, 1+2, 2+3, 3+4, 4+5]
Is it possible to do that with map? If not, is there any other method that is suitable for manipulating multiple array elements in one operation?
here, a and b are treated as the same element
No. a is the value and b is the index. They happen to be the same in your particular data set.
Is it possible to do that with map?
Not with map itself. That will give you a new value for each value in the array, but you are starting with 6 values and ending up with 5, so you need an additional transformation.
Obviously you also need to use "the next value" instead of "the current index" too.
const arr = [0,1,2,3,4,5];
const newarr = arr.map((value, index, array) => value + array[index + 1]);
newarr.pop(); // Discard the last value (5 + undefined);
console.log(newarr);
You could slice the array and map with the value and value at same index of original array.
const
array = [0, 1, 2, 3, 4, 5],
result = array.slice(1).map((v, i) => array[i] + v);
console.log(result);
The second parameter in map is the index. Since map returns results for each iteration you can filter the unwanted item from the new array:
let arr = [0,1,2,3,4,5];
let newarr = arr.map((a,b) => a+arr[b+1]).filter(i => !isNaN(i));
console.log(newarr);
You can use reduce for that:
const arr = [0, 1, 2, 3, 4, 5];
const out = arr.reduce((acc, el, i) => {
if (i === arr.length - 1) { // don't do anything for the last element
return acc;
}
acc.push(el + arr[i + 1]);
return acc;
}, []);
console.log(out)
Using Array.prototype.slice(), Array.prototype.forEach().
const data = [0, 1, 2, 3, 4, 5],
numbers = data.slice(0, -1),
result = [];
numbers.forEach((number, index) => {
result.push(number + data[index + 1]);
});
console.log(result);
I need to find a way to fill an Array with a specific amount of nulls and only replace the last value with a specific number.
My idea would to create an empty Array, set Array.length = desiredLength and set Array[lastElement] = value.
But how to fill the rest?
Example:
Input: Array should have a length of five and last value should be 123
Output: [null, null, null, null, 123]
You could fill the array with expected length minus 1 elements of null, spread that, and finally complemented with the last which is your expected element
Below demo should help you
const length = 5
const lastElem = 123
const res = [...Array(length - 1).fill(null), lastElem]
console.log(res)
Try
array.fill(null, 0, array.length - 1)
And then
array[array.length - 1] = 123
Perhaps
const arr = new Array(4).fill(null)
arr.push(123)
console.log(JSON.stringify(arr))
Using Array.from()
const len = 5
const last = 123
const arr = Array.from({ length: len}, (_, i) => i < len - 1 ? null : last)
console.log(arr)
You can also dynamically make a new array using Array.from or Array.apply, and either use the bult in map function for Array.from or call .map after Array.apply
ES6:
var filled=Array.from(
{length: 5},
(x,i, ar) => i < ar.length - 1 ? null : 123
)
ES5
var filled= Array.apply(0, {length: 5})
.map(function (x, i, ar) {
return i < ar.length -1 ? null : 123
})
use new Array() and Array.fill
function createNullFilledArray(arrayLength, lastValue) {
var arr = (new Array(arrayLength)).fill(null, 0, arrayLength - 1);
arr[arrayLength - 1] = lastValue;
return arr;
}
var outPut = createNullFilledArray(10, 123);
console.log(outPut);
Suppose I have an array as below:
Arr1 = [12,30,30,60,11,12,30]
I need to find index of elements which are repeated in array e.g.
ans: 0,1,2,5,6
I've tried this code but it is considering just single element to check duplicates.
First get all the duplicates using filter() and then using reduce() get he indexes of only those elements of array which are in dups
const arr = [12,30,30,60,11,12,30];
const dups = arr.filter(x => arr.indexOf(x) !== arr.lastIndexOf(x));
const res = arr.reduce((ac, a, i) => {
if(dups.includes(a)){
ac.push(i)
}
return ac;
}, []);
console.log(res)
The time complexity of above algorithm is O(n^2). If you want O(n) you can use below way
const arr = [12,30,30,60,11,12,30];
const dups = arr.reduce((ac, a) => (ac[a] = (ac[a] || 0) + 1, ac), {})
const res = arr.reduce((ac, a, i) => {
if(dups[a] !== 1){
ac.push(i)
}
return ac;
}, []);
console.log(res)
You could use simple indexOf and the loop to get the duplicate indexes.
let arr = [12,30,30,60,11,12,30]
let duplicate = new Set();
for(let i = 0; i < arr.length; i++){
let index = arr.indexOf(arr[i], i + 1);
if(index != -1) {
duplicate.add(i);
duplicate.add(index);
}
}
console.log(Array.from(duplicate).sort().toString());
A slightly different approach with an object as closure for seen items which holds an array of index and the first array, in which later comes the index and a necessary flattening of the values.
This answer is based on the question how is it possible to insert a value into an already mapped value.
This is only possible by using an object reference which is saved at the moment where a value appears and which is not seen before.
Example of unfinished result
[
[0],
[1],
2,
[],
[],
5,
6
]
The final Array#flat removes the covering array and shows only the index, or nothing, if the array remains empty.
[0, 1, 2, 5, 6]
var array = [12, 30, 30, 60, 11, 12, 30],
indices = array
.map((o => (v, i) => {
if (o[v]) { // if is duplicate
o[v][1][0] = o[v][0]; // take the first index as well
return i; // return index
}
o[v] = [i, []]; // save index
return o[v][1]; // return empty array
})({}))
.flat() // remove [] and move values out of array
console.log(indices);
You could use Array#reduce method
loop the array with reduce.At the time find the index of argument
And check the arguments exist more than one in the array using Array#filter
Finaly push the index value to new accumulator array.If the index value already exist in accumalator.Then pass the currentIndex curInd of the array to accumulator
const arr = [12, 30, 30, 60, 11, 12, 30];
let res = arr.reduce((acc, b, curInd) => {
let ind = arr.indexOf(b);
if (arr.filter(k => k == b).length > 1) {
if (acc.indexOf(ind) > -1) {
acc.push(curInd)
} else {
acc.push(ind);
}
}
return acc;
}, []);
console.log(res)
Below code will be easiest way to find indexes of duplicate elements
var dupIndex = [];
$.each(Arr1, function(index, value){
if(Arr1.filter(a => a == value).length > 1){ dupIndex.push(index); }
});
This should work for you
I would like to compound values while mapping an array, I tried this but it didn't work:
var array = children.map((child, i) => {
return child.offsetHeight + array[i-1]
})
I would like an array that looks like this:
[1, 5, 3, 2]
to output:
[1, 6, 9, 11]
Using map is not a requirement. But I don't mind using something more intended than a for-loop.
Here an alternative way to other proposals and simple one-liner by using a forEach-loop:
let a = [1, 5, 3, 2],
b = [];
a.forEach((el, it) => { b.push(el + (b[it - 1] || 0)) });
console.log(b)
(b[it - 1] || 0) covers the first iteration where we would access b[-1]
You can use a combination of Array#map, Array#slice and Array#reduce :
.map( ... ) goes through your array
.slice( ... ) cuts a part from your array, from beginning to i+1
.reduce( ... ) returns the sum of the previously cut array
let children = [1, 5, 3, 2];
var array = children.map((child, i) =>
children.slice(0,i+1).reduce((acc, curr) => acc + curr, 0));
console.log(array);
This is one way:
const input = [1, 5, 3, 2];
const result = input.reduce((arr, x, i) =>
i == 0 ? [x] : [...arr, x + arr[arr.length - 1]]
, null)
console.log(result);
Reduce is better than map here, as you get access to the current state, rather than just the current item or the input array.
You can use array#reduce.
var result = [1, 5, 3, 2].reduce((r,v,i) => {
i ? r.push(r[i-1] + v) : r.push(v);
return r;
},[]);
console.log(result);
The easiest solution would be a combination of map slice and reduce:
arr = [1,5,3,2]
result = arr.map((elem, index) => arr.slice(0, index + 1).reduce((a,c) => a+c))
console.log(result)
You can do something like this, you must check at position 0 that array doesn't exist. This solution avoids using reduce and slice each step, improving performance;
var children = [1, 5, 3, 2]
var sum = 0;
var array = children.map((child, i, array) => {
sum = sum + child;
return sum;
})
console.log(array)
Example using for...of:
var arr = [1, 5, 3, 2]
var res = []
var c = 0
for (let item of arr) {
c += item
res.push(c)
}
console.log(res)
//[1, 6, 9, 11]
You could do this with reduce() method instead of map(). So if current index is not 0 you can take last element from accumulator and add current element.
const data = [1, 5, 3, 2]
const result = data.reduce((r, e, i) => {
r.push(i ? +r.slice(-1) + e : e)
return r;
}, []);
console.log(result)
You could also do this with just map() method using thisArg parameter and storing last value inside.
const data = [1, 5, 3, 2]
const result = data.map(function(e) {
return this.n += e
}, {n: 0});
console.log(result)
Or you could just create closure with IIFE and inside use map() method.
const data = [1, 5, 3, 2]
const result = (s => data.map(e => s += e))(0)
console.log(result)