How can I subtract numbers from array in JavaScript? - javascript

For example: [5, 4, 1] = 0
If it is easy question, I'm so sorry, but I'm new in JavaScript! Thanks from all answers

Use Array.prototype.reduce to reduce and Array to a single output:
const numbers = [5, 4, 1];
const sub = numbers.reduce((acc, num) => acc - num);
console.log(sub) // 0

Using a for loop and if else:
const numbers = [5,4,1] ;
let ans = 0; //Initialize ans with some value
if(numbers.length > 0) ans = numbers[0]; //If array has length >0, use the first value. This will let you handle single length arrays
for(let i = 1; i < numbers.length;i++){
ans -= numbers[i]; //subtract for every other element
}
console.log(ans);

You can take a look on Array.reduce function on mozilla docs.
const subtractNumbersFromArray = (arr) => {
return arr.reduce((acc, currentValue) => acc - currentValue);
};
const result = subtractNumbersFromArray([5, 4, 1]) // 0
const result = subtractNumbersFromArray([10, 3, 2]) // 5

Related

Creating an array from another array

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 );

How to multiply array values without nested loops

Problem:
Given an array of integers, return a new array such that each element at index i of the new array is the product of all the numbers in the original array except the one at i.
For example:
if our input was [1, 2, 3, 4, 5], the expected output would be [120, 60, 40, 30, 24].
If our input was [3, 2, 1], the expected output would be [2, 3, 6].
Solution 1 (With Nested loops): I'm able to solve this by nested loops like below:
const input = [1, 2, 3, 4, 5];
function output(items) {
const finalArray = [];
for (let i = 0; i < items.length; i++) {
let multipliedNum = 1;
items.forEach((item, indx) => {
if (i !== indx) {
multipliedNum = multipliedNum * item;
}
});
finalArray.push(multipliedNum)
}
return finalArray;
}
console.log(output(input))
I'm trying to find out another solution without nested loops inside output function? Any help or suggestion really appreciated.
If there are no zero values, you can loop through all the values once to get the product. Then just return the array where each the product is divided by each entry.
However, if there are zeros then there is a little more to be done to check how many there are. One zero is fine but more than 1 means that the value is zero for each entry.
const input = [1, 2, 3, 4, 5];
const input2 = [1, 2, 3, 4, 0];
const input3 = [1, 2, 3, 0, 0];
function output(items) {
let zeroCount = 0;
let totalProduct = 1;
for (let i = 0; i < items.length; i++) {
if (items[i] === 0) {
if (++zeroCount > 1) break;
continue;
}
totalProduct *= items[i];
}
if (zeroCount > 1) {
// more than 1 zero -> all values are 0
return new Array(items.length).fill(0);
} else if (zeroCount === 1) {
// only 1 zero -> only the value that is zero will be the totalProduct
return items.map(item => item === 0 ? totalProduct : 0);
}
// no zero in array -> divide the totalProduct by each item
return items.map(item => totalProduct / item);
}
console.log(output(input))
console.log(output(input2))
console.log(output(input3))
Based on what #Mike said in the comment here's the answer.
const input = [1, 2, 3, 4, 5];
const mulValues = input.reduce((acc, next) => acc * next);
const output = input.map(i => mulValues/i)
console.log(output)
you can do something like that (assuming array doesn't contain zero):
calculate product of all array elements
divide product by element at position [i] to get the desired output
const input = [1, 2, 3, 4, 5];
function output(items) {
const finalArray = [];
const multipliedNum=1;
for (let i = 0; i < items.length; i++) {
multipliedNum *= item[i];
}
for (let i = 0; i < items.length; i++) {
finalArray.push(multipliedNum/item[i]);
}
return finalArray;
}
console.log(output(input))
I know this has already been answered, but I think I have a better one.
If you take this issue by a different approach you will see that the product leaving the value at the index out, is also the product devided by value at the index.
If you know use the reduce function, you can simply calculate the product in one line using:
items.reduce((a, b) => a * b)
and then just divide by the value you want to ignore... like this:
items.reduce((a, b) => a * b) / items[index]
if you now want to compress this in one line instead of wrapping it into a for loop block you can simply copy the array and use the map function and the result could look like this:
result = [...items].map((v, i) => items.reduce((a, b) => a * b) / v)
I hope that this helps you to reduce your code

How do I sum the elements of an arbitrary number of arrays with different lengths in Javascript?

While the code below will satisfy adding two arrays with different lengths, how can I modify this to accept an arbitrary number of arrays as arguments so that, for example, ([1, 2, 3], [4, 5], [6]) will return an array of [11, 7, 3] ?
const addTogether = (arr1, arr2) => {
let result = [];
for (let i = 0; i < Math.max(arr1.length, arr2.length); i++) {
result.push((arr1[i] || 0) + (arr2[i] || 0))
}
return result
}
Use a nested array, and loop over the array rather than hard-coding two array variables.
You can use arrays.map() to get all the lengths so you can calculate the maximum length. And arrays.reduce() to sum up an element in each array.
const addTogether = (...arrays) => {
let result = [];
let len = Math.max(...arrays.map(a => a.length));
for (let i = 0; i < len; i++) {
result.push(arrays.reduce((sum, arr) => sum + (arr[i] || 0), 0));
}
return result
}
console.log(addTogether([1, 2, 3], [4, 5], [6]));
You can use arguments object inside function.
arguments is an Array-like object accessible inside functions that contains the values of the arguments passed to that function.
const addTogether = function () {
const inputs = [...arguments];
const maxLen = Math.max(...inputs.map((item) => item.length));
const result = [];
for (let i = 0; i < maxLen; i ++) {
result.push(inputs.reduce((acc, cur) => acc + (cur[i] || 0), 0));
}
return result;
};
console.log(addTogether([1,2,3], [4,5], [6]));
Solution:
const addTogether = (...args) => {
let result = [];
let max = 0;
args.forEach((arg)=>{
max = Math.max(max,arg.length)
})
for(let j=0;j<max;j++){
result[j]= 0
for (let i = 0; i < args.length; i++) {
if(args[i][j])
result[j]+= args[i][j]
}
}
return result
}
console.log(addTogether([1, 2, 3], [4, 5], [6]))
Output:[ 11, 7, 3 ]
Use rest param syntax to accept an arbitrary number of arguments. Sort the outer array by their length in descending order. By using destructuring assignment separate the first and rest of the inner arrays. At last use Array.prototype.map() to traverse the first array as it is the largest array and use Array.prototype.reduce() method to get the summation.
const addTogether = (...ar) => {
ar.sort((x, y) => y.length - x.length);
const [first, ...br] = ar;
return first.map(
(x, i) => x + br.reduce((p, c) => (i < c.length ? c[i] + p : p), 0)
);
};
console.log(addTogether([1, 2, 3], [4, 5], [6]));
Instead of using a for loop that requires you to know the lengths of each array, try using something that doesn't. For example - while loop.
Increment using a dummy variable and reset it for each array and set condition for loop termination as - arr[i] === null.

Reduce over a single array summing slices

I have an array of values
let a = [1,2,3,4,5,6];
I want to sum specific slices, for example a.[0] + a.[1] giving a new array:
[1 + 2, 3 + 4, 5 + 6]
Is there a recommended way to do this with reduce() or other method? Such as some kind of stepping/range parameter?
Because I want #T.J. Crowder to be right :)
const a = [1, 2, 3, 4, 5, 6];
// Loop over all values of the array
const res = a.reduce((tmp, x, xi) => {
// Use Math.floor and xi (the index of the value we are treating)
// to store the values on the returned array at the correct position
tmp[Math.floor(xi / 2)] = (tmp[Math.floor(xi / 2)] || 0) + x;
return tmp;
}, []);
console.log(res);
Will also work if the number of element is not pair
const a = [1, 2, 3, 4, 5];
const res = a.reduce((tmp, x, xi) => {
tmp[Math.floor(xi / 2)] = (tmp[Math.floor(xi / 2)] || 0) + x;
return tmp;
}, []);
console.log(res);
Alternative solution :
const a = [1, 2, 3, 4, 5, 6];
const res = [];
do {
res.push(a.splice(0, 2).reduce((tmp, x) => tmp +x, 0));
} while (a.length);
console.log(res);
You can do this with reduce, but it's not the right tool for the job. Here's how, keying off index and passing an array around:
let array = [1,2,3,4,5,6];
let result = array.reduce((a, v, i) => {
if (i % 2 == 1) {
// It's an odd entry, so sum it with the
// previous entry and push to the result array
a.push(v + array[i - 1]);
}
return a;
}, []);
console.log(result);
You can squash that into a concise arrow function, at the expense of clarity:
let array = [1,2,3,4,5,6];
let result = array.reduce((a, v, i) => ((i % 2 === 1 ? a.push(v + array[i - 1]) : 0), a), []);
console.log(result);
A simple for loop would probably be more appropriate, though:
let array = [1,2,3,4,5,6];
let result = [];
for (let n = 0; n < array.length; n += 2) {
result.push(array[n] + array[n + 1]);
}
console.log(result);
Another approach with Array#flatMap and taking only the odd indices for a value.
var array = [1, 2, 3, 4, 5, 6],
result = array.flatMap((v, i, { [i + 1]: w = 0 }) => i % 2 ? [] : v + w);
console.log(result);
A simple and quick solution with [Array.prototype.reduce] can look like this:
const array = [1,2,3,4,5,6];
const range = 2;
const result = array.reduce((all, item, i) => {
const idx = Math.floor(i/range);
if (!all[idx]) all[idx] = 0;
all[idx] += item;
return all;
},[]);
console.log(result);

Mini-Max Sum In JavaScript - How to Get the Minimum Sum And Maximum Sum of 4 Elements in a 5-Element Array

Link to HackerRank Challenge
My idea is to loop through the array and sum all elements in the array except for one element each time, then find the smallest sum and the largest sum.
I know that .splice() can remove any element from an array. But currently, with my code, it's only removing one element from the array once. I.e. this is only giving me one chunk:
function miniMaxSum(arr) {
let smallestSum = 0;
let largestSum = 0;
for (let i = 0; i < arr.length; i++) {
let chunk = arr.splice(1);
console.log(chunk);
if (chunk > largestSum) largestSum = chunk;
if (chunk < smallestSum) smallestSum = chunk;
}
return (smallestSum, largestSum);
}
I need to remove one element from the array every time while looping, then get the max and min sums from that array.
So for given array of [1, 2, 3, 4, 5]
I should get the following possible "chunks":
[2, 3, 4, 5], [1, 3, 4, 5], [1, 2, 4, 5], [1, 2, 3, 5], [1, 2, 3, 4].
The chunk with the highest sum is [2, 3, 4, 5]
And the chunk with the smallest sum is [1, 2, 3, 4].
How can I adjust my code to get all of the possible 4-digit arrays within the given array so that I can compare their sums, still using a for-loop? Or if not with a for-loop, what else would you suggest?
EDIT: Now using Math.min() and Math.max() to get the smallest and largest elements in the array. Then using .filter() to remove those elements in order to create new arrays. Then getting the sums of those arrays.
function miniMaxSum(arr) {
let smallest = Math.min(...arr);
let largest = Math.max(...arr);
let smallestArray = arr.filter(element => element !== largest);
let largestArray = arr.filter(element => element !== smallest);
let sumOfSmallestArray = 0;
let sumOfLargestArray = 0;
for (let i = 0; i < smallestArray.length; i++) {
sumOfSmallestArray += smallestArray[i];
}
for (let i = 0; i < largestArray.length; i++) {
sumOfLargestArray += largestArray[i];
}
return ([sumOfSmallestArray, sumOfLargestArray]).toString();
}
But even though it works in my console, it doesn't work in HackerRank.
The key is to sort that array first, then the minimum will be the first element and the maximum will be the last, hence if you want to get the minimum set, it will be the array without the highest value (last element) and if you want to get the maximum set it will be the array without the lowest value (first element).
let data = [1, 3, 2, 4, 5];
// sort first
data = data.sort((a, b) => a - b);
// to get the sets only
let maxSet = data.slice(1);
let minSet = data.slice(0, -1);
console.log(minSet, maxSet);
// to get just the max/min value
const sum = data.reduce((a, total) => a + total, 0);
console.log(sum - data[data.length - 1], sum - data[0]);
The HackerRank challenge just asks for the sums of the, so you can make one pass through the array to calculate 3 facts:
Maximum element (a)
Minimum element (b)
Total sum of all elements (c)
The sum of the smallest chunk will be c - a and the sum of the largest will be c - b.
Here's a one-liner solution using reduce:
var arr = [1, 2, 3, 4, 5];
var [a, b, c] = arr.reduce(([a, b, c], x) => [a > x ? a : x, b < x ? b : x, c + x], [NaN, NaN, 0]);
console.log(c - a, c - b);
Note: the NaN's are just here to force the initial conditions (a > x/b < x to be false)
You could get the min and max values of the array and filter the array by taking not min or max value once.
var data = [1, 2, 3, 4, 5],
min = Math.min(...data),
max = Math.max(...data),
dataMin = data.filter(v => v !== min || !(min = -Infinity)),
dataMax = data.filter(v => v !== max || !(max = Infinity));
console.log(...dataMin);
console.log(...dataMax);
A more classical approach
function minMax(array) {
var min = array[0],
max = array[0],
sum = array[0],
i, v;
for (i = 1; i < array.length; i++) {
v = array[i];
sum += v;
if (v > max) max = v;
if (v < min) min = v;
}
console.log(sum - min, sum - max);
}
minMax([1, 2, 3, 4, 5]);
You can sort the array and for min take first four and add them and for max take last four and add them
let arr = [1, 2, 3, 4, 5]
let minAndMax = (arr) => {
arr = arr.sort((a,b) => a - b)
let op = {}
op.minArr = arr.slice(0,4)
op.min = op.minArr.reduce((a,b) => a+b, 0)
op.maxArr = arr.slice(arr.length-4,)
op.max = op.maxArr.reduce((a,b) => a + b ,0)
return op
}
console.log(minAndMax(arr))
This solution traverses the slice indexes, calculates the sum and when a maximum is found, it is put into result. Finally result is parsed:
var arr = [4, 8, 2, 6, 12];
var ln = arr.length;
var maxSum = undefined;
var result = "";
for (var splIndex = 0; splIndex < ln; splIndex++) {
var item = arr.splice(splIndex, 1);
var sum = 0;
for (var it of arr) sum += it;
if ((maxSum === undefined) || (maxSum < sum)) {
maxSum = sum;
result = JSON.stringify(arr);
}
arr.splice(splIndex, 0, item[0]);
}
console.log(JSON.parse(result));
EDIT
A simpler solution, of course is to find the minimum and calculate the sum without it.
The following function works:
function miniMaxSum(arr) {
var _arr = arr.sort((a, b) = > a - b)
var minVals = _arr.slice(0, 4)
var maxVals = _arr.slice(1)
const arrSum = __arr = > __arr.reduce((a, b) = > a + b, 0)
var minSum = arrSum(minVals)
var maxSum = arrSum(maxVals)
console.log(minSum, maxSum)
}
let arr = [15 ,12, 33, 25, 4];
//sort array
const arrSort = arr.sort((a,b)=> a-b );
console.log(arrSort);
//get values and sum
var max = arrSort.filter(value => value < Math.max(...arrSort)).reduce((ac,at)=>{
ac += at;
return ac;
},0);
var min = arrSort.filter(value => value > Math.min(...arrSort)).reduce((ac,at)=>{
ac += at;
return ac;
},0);
console.log(max);
console.log(min);
This worked for me.
let minValue, maxValue
const ascendingArray = arr.sort((a,b) => a - b)
const smallestNumber = ascendingArray[0]
const biggestNumber = ascendingArray[ascendingArray.length -1]
if(smallestNumber !== biggestNumber){
const biggestArray = arr.filter((number) => {
return number !== smallestNumber
})
const smallestArray = arr.filter((number) => {
return number !== biggestNumber
})
minValue = smallestArray.reduce((a,b) => a + b, 0)
maxValue = biggestArray.reduce((a,b) => a + b, 0)
console.log(minValue, maxValue);
}
else{
const arraySliced = arr.slice(0, 4)
const value = arraySliced.reduce((a,b) => a + b, 0)
console.log(value, value);
}
function miniMaxSum(arr) {
var soma = 0
let t = 0
for (var i = 0; i < arr.length; i++) {
soma += arr[i]
max = soma - arr[i]
}
let min = soma - arr[0]
return max + ' ' + min
}
console.log(miniMaxSum([7, 69, 2, 221, 8974]))
Here is a cleaner approach to solving this problem.
function miniMaxSum(arr) {
let min, max, sum, arrMin, arrMax; // declare variables
min = Math.min(...arr) // gets the smallest value from the arr
max = Math.max(...arr) // gets the largest number from the arr
sum = arr.reduce((a,b) => a+b, 0); // reduce used to add all values in arr
arrMin = sum - max; // excludes the largest value
arrMax = sum - min; // excludes the smallest value
console.log(arrMin+' '+arrMax) // output
}
easy solution
const miniMax = arr => {
let min = arr[0];
let max = arr[0];
for(let i = 0; i < arr.length; i++) {
if(arr[i] <= min) {
min = arr[i];
}
if (arr[i] >= max) {
max = arr[i];
}
}
let sum = arr.reduce((acc,curr) => acc + curr);
console.log(sum - max, sum - min);
}
miniMax([5,5,5,5,5]);
// result : 20 20
miniMax([1,2,3,4,5]);
// result : 10 14
I get Answer in very Simple way
function miniMaxSum(arr) {
let minval=arr[0];
let maxval=0;
let totalSum=0;
for(let i=0;i<arr.length;i++){
if (arr[i]>maxval){
maxval=arr[i];
}
if (arr[i]<minval){
minval=arr[i];
}
totalSum=totalSum+arr[i];
}
let minsum=totalSum - maxval;
let maxsum=totalSum - minval;
console.log( minsum,maxsum);
}
Use build Math methods to find max and min:
function miniMaxSum(arr) {
const min = Math.min(...arr);
const max = Math.max(...arr);
const sum = arr.reduce((a, b) => a + b);
console.log(sum - max, sum - min);
}

Categories

Resources