Iteratively adding up first and last numbers in an array - javascript

I'm trying to write a function that continually adds together the first and last elements of an array using forEach with array.shift() + array.pop().
The problem is that the for-loop doesn't complete the innermost numbers, and so the array is always left with 2 values inside of it.
Code:
function choreAssignment(chores) {
chores.sort(function(a, b) {return a - b});
var assignment = [];
chores.forEach(function() {
assignment.push((chores.pop() + chores.shift()));
});
return assignment.sort(function(a, b) {return a - b});
}
The above code works as expected, but it leaves the innermost two values inside the chores array.
For example if I run:
Code:
var arr = [1, 4, 7, 2, 5, 9, 4, 3];
choreAssignment(arr);
I get:
[8, 9, 10]
Ie, it adds 9 & 1, 7 & 2, 5 & 3, but it leaves [4, 4] inside the array.
I'm not sure why this is. Thank you.

Try changing the forEach to:
while (chores.length) {
assignment.push((chores.pop() + chores.shift()));
}
Note this assumes there are always an even number of elements in array

Related

forEach seems to be working for push() function but didn't work for pop() in JavaScript. can someone tell me what I am doing wrong

//code1
let a= [1, 3 , 4, 6];
[7, 8 , 9].forEach(l => a.push(l));
console.log(a);
// [1, 3, 4, 6, 7, 8, 9 ]
1.it worked for push() function
//code2
let a= [1, 3 , 4, 6];
a.forEach(l => a.pop(l));
console.log(a);
//[ 1, 3 ]
2. didn't work for pop() though
Javascript Array.pop() removes the last element from the array and returns that.
Example:
var arr = [1,2,3]
arr.pop(); // returns 3
Reference
If you want to remove a element with specific value than try something like:
var arr = [1, 2, 3];
var index = arr.indexOf(1);
if (index > -1) {
array.splice(index, 1);
}
var arr = [1, 2, 3, 4];
console.log(arr.pop());
var index = arr.indexOf(2);
if (index > -1) {
arr.splice(index, 1);
}
console.log(arr)
forEach automatically extracts the elements one by one and gives them to you
It starts from the beginning of the array, and does them all.
It doesn't delete elements from the array.
a = [1, 3, 4, 6];
a.forEach(item => console.log(item));
// output is in forwards order
// and 'a' retains original contents
pop() extracts and deletes one element for you
It starts from the end of the array, and does only one.
It deletes the element from the array.
a = [1, 3, 4, 6];
while (a.length > 0) {
console.log(a.pop())
}
// items come out in reverse order
// and 'a' is being emptied so it is [] at the end
Choose your method
Do you want the last element actually removed from the array? This is what you would want if you were implementing a stack, for example. In that case, use ".pop()".
This gets one element from the end of the array and deletes it from the array.
Or do you want to just look at each element in turn from the array (starting at the beginning), without changing the array itself. This is a commoner situation. In this case, use ".forEach"

group items in array in javascript

I have an array of items, can be objects with many properties, and I want to group some of these items based on order:
example:
[a,b,c,d,e] => [a,[b,c,d],e]
must group (b, c, d) or (a) or (b, c) or (all)
must not group (a, c) or (a, d) for example because they are not sequential
Some possibilites:
[a,b,c,d] to [[a,b,c,d]]
[a,b,c,d] to [[a],b,c,d]
[a,b,c,d] to [[a,b],c,d]
[a,b,c,d] to [[a,b,c],d]
[a,b,c,d] to [a,b,[c,d]]
always sequential items
think of item a like an object with index;
If I understand correctly, you want to group n sequential elements of the array starting from an index ind and put that that group back into the array at the same index. You can acheive that using splice:
function group(arr, ind, n) {
var g = arr.splice(ind, n); // cut out n elements from the array at index ind
arr.splice(ind, 0, g); // push back those cut-out elements into the same index ind (the elements are in array because of the first slpice call)
}
var arr = [1, 2, 3, 4, 5, 6];
group(arr, 2, 3);
console.log(arr); // [1, 2, [3, 4, 5], 6]
EDIT:
As requested, changing group to create a new array instead of altering the original and taking start and end indexes. So for that we are going to use slice/concat instead of splice:
function group(arr, start, end) {
return [].concat(arr.slice(0, start), [arr.slice(start, end + 1)], arr.slice(end + 1));
}
var arr = [1, 2, 3, 4, 5, 6];
console.log(group(arr, 2, 3)); // => [1, 2, [3, 4, 5], 6]
console.log(group(arr, 4, 6)); // => [1, 2, 3, 4, [5, 6]]
console.log(group(arr, 0, 3)); // => [[1, 2, 3, 4], 5, 6]
which concatinate the subarrays: from 0 to start, from start to end + 1 (put in an array of its own so its stays grouped) and from end + 1 onward. If you want the end index to be exclusive (the element at end not included) then just change end + 1 to end.
Based on the more recent comments you may be looking for Array's own, built-in slice method, it provides a continuous sub-region of an array, where start and end positions are its arguments:
function format(a){return "["+a.join(",")+"]";}
var arr=['a','b','c','d','e'];
console.log("original: "+format(arr));
console.log("slice(0,1): "+format(arr.slice(0,1)));
console.log("slice(0,2): "+format(arr.slice(0,2)));
console.log("slice(1,4): "+format(arr.slice(1,4)));
console.log("slice(2,4): "+format(arr.slice(2,4)));
console.log("slice(2,2): "+format(arr.slice(2,2)));
Note 1: The second argument is the position of the "last+1" element you want, it is best seen in the last example where slice(2,2) provides an empty array
Note 2: format is just about getting array contents in one line, console.log(somearray) displays the elements vertically.
Then of course you can do whatever you need, but it is definitely worth to note that this function exists and it is built-in.
Like building the array-in-array thing you describe:
function format(a){var s="[",first=true;a.forEach(function(i){
if(first)first=false;else s+=",";s+=i instanceof Array?format(i):i;});
s+="]";return s;}
function group(arr,begin,end){
var ret=[];
for(var i=0;i<begin;i++)ret.push(arr[i]);
ret.push(arr.slice(begin,end));
for(var i=end;i<arr.length;i++)ret.push(arr[i]);
return ret;
}
var arr=['a','b','c','d','e'];
console.log("original: "+format(arr));
console.log("group(arr,0,1): "+format(group(arr,0,1)));
console.log("group(arr,0,2): "+format(group(arr,0,2)));
console.log("group(arr,1,4): "+format(group(arr,1,4)));
console.log("group(arr,2,4): "+format(group(arr,2,4)));
console.log("group(arr,2,2): "+format(group(arr,2,2)));
Examples are the same as for the slice-explanation, including the empty array in the last one (with 2,2). It is up to you if you want such empty element (as kind of a 'cursor') or not.
And of course the thing also works with the nested loops in my original answer, if you want to generate all possible selections from an array - that is how your question initially seemed to me:
function format(a){var s="[",first=true;a.forEach(function(i){
if(first)first=false;else s+=",";s+=i instanceof Array?format(i):i;});
s+="]";return s;}
function group(arr,begin,end){
var ret=[];
for(var i=0;i<begin;i++)ret.push(arr[i]);
ret.push(arr.slice(begin,end));
for(var i=end;i<arr.length;i++)ret.push(arr[i]);
return ret;
}
var arr=['a','b','c','d','e'];
console.log("original: "+format(arr));
for(var i=0;i<arr.length;i++)
for(var j=i+1;j<=arr.length;j++){
console.log(format(group(arr,i,j)));
}

Find largest adjacent product in array (JavaScript)

I'm trying to understand the following solution for finding the largest adjacent product in any given array.
Example:
For inputArray = [3, 6, -2, -5, 7, 3], the output should be
adjacentElementsProduct(inputArray) = 21.
7 and 3 produce the largest product.
Possible solution in JS:
function adjacentElementsProduct(arr) {
return Math.max(...arr.slice(1).map((x,i)=>[x*arr[i]]))
}
I am having a hard time understanding two things:
What do the three dots exactly do and how does this get passed into the function? Is there any way to write this in a more understandable way? I know that is the "spread syntax" feature in ES6, but still don't understand completely.
Why do we insert "1" as argument to slice? My first though was to input "0", because we want to start at the start, then loop through everything, and see which adjacent product is the largest.
I'd appreciate any advice, links and explanations.
Thanks.
Cheers!
1. What do the three dots exactly do and how does this get passed into the function? Is there any way to write this in a more understandable way? I know that is some kind of "spread" feature in ES6, but still don't understand completely.
The Math#max needs a list of numbers as parameters, and map produces an array. The spread syntax is used to convert an array to be expanded to a list of parameters.
const arr = [1, 2, 3];
console.log('max on array', Math.max(arr));
console.log('max on list of parameters', Math.max(...arr));
In this case you can use Function#apply to convert the array to a list of parameters. I find it less readable, however.
const arr = [1, 2, 3];
console.log(Math.max.apply(Math, arr));
2. Why do we insert "1" as argument to slice? My first though was to input "0", because we want to start at the start, then loop through everything, and see which adjacent product is the largest.
Lets break down the iteration order of the 2 arrays.
[3, 6, -2, -5, 7, 3] // inputArray
[6, -2, -5, 7, 3] // inputArray.slice(1)
Now on each iteration of inputArray.slice(1):
x: 6, i = 0, arr[0] = 3
x: -2, i = 1, arr[1] = 6
x: -5, i = 2, arr[2] = -2
Since the inputArray.slice(1) array starts from the 2nd element of the inputArray, the index (i) points to the 1st element of the inputArray. And the result is an array of products of 2 adjacent numbers.
var biggestProduct = inputArray[0] * inputArray[1];
for (i=0; i<inputArray.length-1 ; ++i)
{
console.log(biggestProduct)
if ((inputArray[i] * inputArray[i+1] ) > biggestProduct)
{
biggestProduct = inputArray[i] * inputArray[i+1]
}
}
return biggestProduct;
Note: I've declared a variable that consists of 2 input arrays with index number then starts a for loop that indicates input array with his index number, so by that he will go throw all the index number of the array (one of them raised by one so that they won't be at the same value). and at the end of the code, you have the if statement.
You may simply do as follows;
function getNeigboringMaxProduct([x,...xs], r = -Infinity){
var p = x * xs[0];
return xs.length ? getNeigboringMaxProduct(xs, p > r ? p : r)
: r;
}
var arr = [3, 6, -2, -5, 7, 3],
res = getNeigboringMaxProduct(arr);
console.log(res);

Choose if array element repeats itself twice -- Javascript [duplicate]

This question already has answers here:
Get all non-unique values (i.e.: duplicate/more than one occurrence) in an array
(97 answers)
Closed 6 years ago.
There is a javascript array
var arr = [0, 1, 2, 2, 3, 3, 5];
I want to choose elements that repeats twice. In this case its 2 and 3. and i want attach them into a variable.
var a = 2, b = 3;
As far as i know there is no built-in function to do that job. How can i do that. Thanks.
You can use filter to get the values that occur twice.
var arr = [0, 1, 2, 2, 3, 3, 5];
var dups = arr.filter ( (v,i,a) => a.indexOf(v) < i );
console.log(dups);
In comments you stated you would only have doubles, but no values that occur more than twice. Note that the above would return a value more than once, if the latter would be the case.
This returns the values in an array, which is how you should work. To put them in separate values can be done as follows:
var [a, b, ...others] = dups;
...but you would have to know how many variables to reserve for that, and it does not make your further program any easier. JavaScript has many nice functions (methods) for arrays, so you should in fact leave them in an array.
There is no built in function to do that indeed.
You will have to loop thought the array and keeping track of the number of occurrences of the elements, while building a response array.
You could filter a sorted array.
var arr = [0, 1, 2, 2, 3, 3, 5],
repeats = arr.filter(function (a, i, aa) {
return aa[i - 1] === a;
});
console.log(repeats);
Most simple way to do this is the following:
var dups = [];
var arr = [0, 1, 2, 2, 3, 3, 5];
arr.forEach(function (v, i, a){
delete arr[i];
if (arr.indexOf(v) !== -1){
dups.push(v);
}
});
console.log(dups);
It's destructive however.

Finding the lowest number in an array using split('') and reverse();

I am trying to find the min value of an array, and am trying to do it by sorting the array, and then reversing the array, and then calling the very first index of the array.
Unfortunately with what I have been trying, I keep getting 9. (don't know why) Can anybody take a quick look at what I have been doing and bail me out here? (i'm using js)
var minny = [4, 3, 5, 2, 6, 3, 4, 5, 2, 3, 4, 6, 7, 8, 9, 9, 1, 11, 25];
var smallest = function (minny){
minny = minny.sort('');
var sorted = minny + " ";
sorted = minny.reverse('').join('');
return sorted[0];
}
console.log(smallest(minny))
By default the sort method sorts elements alphabetically(11 comes before 9) and therefore you need to add a compare function as a param.
var smallest = function (minny) {
minny = minny.sort(function(a, b) { return a - b; });
return minny[0];
}
console.log(smallest(minny))
JSFIDDLE.
Based on your code, you could just do
return minny.sort()[0];
So, your full code example becomes
var minny = [4, 3, 5, 2, 6, 3, 4, 5, 2, 3, 4, 6, 7, 8, 9, 9, 1, 11, 25];
var smallest = function (minny){
return minny.sort()[0];
}
console.log(smallest(minny))
You're calling minny.sort('') which is using the default natural sort, so 11 and 25 end up near the beginning because of the 1 and 2.
What you have to do is call sort with a function that compares numbers, such as:
minny.sort(function(a,b) { return b-a; });
This will sort minny the way you want it.
There is no need to even call reverse and join afterwards, just return the first item. "return sorted[0]" is fine but will fail if there are no items, so you might just want to call "return sorted.shift()" instead. This will return the first item too, but won't fail if the array is empty.
PS. your call to minny.reverse also has an empty string as a parameter. That's not needed, reverse takes no parameters.
sort() sorts alphabetically by string representation, so in your case it would result in 1, 11, 2, 2, 25, .... You have to provide a comparison function for correct integer sorting, although in your specific case it doesn't really make a difference.
var smallest = function (minny){
minny = minny.sort(function(a, b){return a-b});
return minny[0];
}
See jsfiddle
Using sort is fairly short code to write, and it will return the correct number if you use minny.sort(function(a,b){return a-b})[0].
If you have a large unordered array you are running the comparison many times and you are sorting the array, which is not usually what you want to do to an array.
It may be better to just iterate the members and compare each just once to the lowest fond so far.
var minny= [4, 3, 5, 2, 6, 3, 4, 5, 2, 3, 4, 6, 7, 8, 9, 9, 1, 11, 25];
var smallest= function(minny){
var min= Infinity;
minny.forEach(function(next){
if(next<min) min= next;
});
return min;
}
Or use Math.min, if this is code golf:
Math.min.apply(Array,minny);

Categories

Resources