I wish to execute a program with output as :
console.log(range(1, 10));
// → [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
console.log(range(5, 2, -1));
// → [5, 4, 3, 2]
console.log(sum(range(1, 10)));
// → 55
I am getting an error for array.length.Please find the code below:
var array = [];
function range (arr){
var lower = Math.min(arr[0],arr[1]);
var upper = Math.max(arr[0],arr[1]);
for (var i=lower;i<=upper;i++){
array.push(i);
}
}
function sum(array){
for(var i=0;i < array.length;i++){
var total = total+array[i];
}
}
console.log(sum(range(1, 10)));
I am at begineers level, please do help.
Thanks.
You have a few problems here:
1.) You aren't returning anything in your range function. You need to return the filled array.
2.) You aren't passing the array correctly in the sum function call.
3.) You aren't returning anything in your sum function call.
Without returning any values, you aren't letting your code blocks work with eachother
var array = [];
function range (arr){
var lower = Math.min(arr[0],arr[1]);
var upper = Math.max(arr[0],arr[1]);
for (var i=lower;i<=upper;i++){
array.push(i);
}
return array; // return the array to be used in the sum function
}
function sum(array){
var total = 0; // need to create a variable outside the loop scope
for(var i in array){
total = total+array[i];
}
return total;
}
console.log(sum(range([1,10]))); // pass the array correctly
Note that you need to set the total variable outside the scope of the for-loop within the sum function. That way you can return the final value. Otherwise, it would return undefined.
See the fiddle: https://jsfiddle.net/udyhb95a/
You need to pass an array when calling the range function you defined range([1, 10])
You need to rewrite your sum function
As a side note, there are more efficient ways to compute the sum of a range of elements without iterating on them.
function sum_of_range(start, end) {
return end * (end + 1) / 2 - start * (start + 1) / 2;
}
Edit:
Here is a working sum function
function sum(array) {
var accumulator = 0;
for (var i = 0; i < array.length; ++i)
accumulator += array[i];
return accumulator;
}
Here you declare a function with one parameter as an array
function range (arr){
...
But here you call a function with two arguments as numbers
console.log(range(1, 10));
Use this call function
console.log(range([1, 10]));
And don't use for..in for arrays
for(var i in array){ it doesn't work as you expect
Use forEach function or plan for loop
Also you have some error in sum function
See working example below:
function range(arr) {
var array = [];
var lower = Math.min(arr[0], arr[1]);
var upper = Math.max(arr[0], arr[1]);
for (var i = lower; i <= upper; i++) {
array.push(i);
}
return array;
}
function sum(array) {
var total = 0;
for (var i = 0; i < array.length; i++) {
total = total + array[i];
}
return total;
}
document.write('range ' + range([1, 10]) + '<br>');
document.write('sum ' + sum(range([1, 10])));
You need to modify sum & range function
function range (){
var array = [];
var lower = Math.min.apply(null, arguments);
var upper = Math.max.apply(null, arguments);
for (var i=lower;i<=upper;i++){
array.push(i);
}
return array;
}
function sum(array){
return array.reduce((x,y)=>x+y,0);
}
console.log(range(1, 10));
// [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
console.log(range(5, 2, -1)); //if we are considering min & max from params
// [-1, 0, 1, 2, 3, 4, 5]
console.log(sum(range(1, 10)));
// 55
Hello Dear check it now.
var array = [];
function range(arr, arr1) {
var lower = Math.min(arr);
var upper = Math.max(arr1);
for (var i = lower; i <= upper; i++) {
array.push(i);
}
}
function sum() {
var total = 0;
for (var i = 0; i < array.length; i++) {
total = total + array[i];
}
return total;
}
console.log(sum(range(1, 10)));
This is the correct answer to the problem at the end of the data structures chapter within Eloquent JavaScript
function range(start, end, step) {
let arr = []; //declare an empty array
var step = step || 1;//tests to see if step was supplied, otherwise it's 1
if(start < end)
{
for(let i = start; i <= end; i += step)
{
arr.push(i);
}
}
else
{
for(let i = start; i >= end; i += step)
{
arr.push(i);
}
}
return arr;
}
function sum(array) {
let total = 0;
for(let i = 0; i < array.length; i++)
{
total += array[i];
}
return total;
}
console.log(range(1, 10));
// → [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
console.log(range(5, 2, -1));
// → [5, 4, 3, 2]
console.log(sum(range(1,10)));
// → 55
This solution takes into account of entering a step that isn't expected to be positive/negative, i.e range from 1 to 5, we would expect step to be positive, but if the user somehow entered a negative step then an empty array would occur.
The browser actually hangs for the opposite, if the array is expected to decrease, but the step sizes are > 0.
'use strict';
function range(start, end, step = 1){
let output = [];
if (start > end){
// Sanity check, all steps if expected to go down should be negative
if (step > 0){
step = -step;
}
for (;start >= end; start += step){
console.log(start);
output.push(start);
}
}
else{
// Likewise, as all steps should be positive
if (step < 0){
step = -step;
}
for (;start <= end; start += step){
output.push(start);
}
}
return output;
}
function sum(arr){
let output = 0;
for (let i of arr){
output += i;
}
return output;
}
console.log(range(1, 5, 1));
// → [1, 2, 3, 4, 5]
console.log(range(5, 1, -1));
// → [5, 4, 3, 2, 1]
// Notice this one step is a positive, but this is handled (original solution returned empty array)
console.log(range(5, 1, 1));
// → [5, 4, 3, 2, 1]
console.log(sum(range(1,10)));
// → 55
An improvement onto this is to use the reduce function for an array to sum instead of a for loop, i.e:
function sum(array){
return array.reduce((x,y)=>x+y,0);
}
For people finding this later on as I did, here is a way to write the range function so you can pass the input as written in the original question:
console.log(sum(range(1, 10)));
…and a cleaned up sum function similar to the one in A. Sharma's answer:
function range(lower, upper) {
let array = []
for (let i = lower; i <= upper; i++) {
array.push(i);
}
return array;
}
function sum(array) {
let total = 0;
for (let i in array) {
total = total + array[i];
}
return total;
}
console.log(sum(range(1, 10)));
Also worth mentioning:
The use of reduce in JagsSparrow's answer, which is elegant, while not entirely obvious and newcomer friendly as Mathias Vonende pointed out.
Negative step tolerant versions in answers from Jimmy Wei and user3225968.
This is the best solution I've got
function range(x,y){
var arr = [];
for(x;x<=y;x++){
arr.push(x);
};
return arr;
};
function sum(array){
return array.reduce((a,b) => a + b, 0);
};
console.log(sum(range(1,10)));
This answer is quite late but I am learning these things now and want to share my solution. I have not seen this solution provided for the specific question "Sum of a range in Javascript" so I wanted to share it. What I have done here is made use of the pop method for the array which allowed me not to specifically pass an array argument to the range function but to provide a solution to the argument in the way it was originally presented in the question.
var result = [];
var counter = 0;
function range(start, end) {
for (let i = start; i <= end; i++) {
result.push(i);
}
return result;
}
function sum(array) {
for (let i = 0; i < result.length; i++) {
counter += result.pop(i);
}
return counter;
}
console.log(range(1, 10));
// → [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
console.log(sum(range(1, 10)));
// → 55
This can be accomplished very easily and efficiently without any globally scoped vars.
It's not clear in the original question what behavior should be applied to the -1 argument. It seems to be an indicator to reverse the range. In the below example, I've used a boolean to check this argument. A value of -1 would actually be the same as not providing a third argument. To reverse the range, pass in any truthy value.
function range(from, to, reverse) {
// Make sure our inputs are actually numbers
if (Number(from) != from || Number(to) != to) {
throw new TypeError("range() expects a Number as both it's first and second argument");
}
let o = []; // initialize our output array
// get the lowest value argument as our starting index
let i = Math.min(from, to);
// get the highest value argument as our ending index
let x = Math.max(from, to);
// push i onto our output array and then increment until i == x
while (i <= x) { o.push(i); i++; }
// reverse the range order if necessary
if (reverse) { o = o.reverse(); }
// return our output array
return o;
}
Then we can use Array.reduce to iterate through the range array and add each value (b) to the one before it (a) with the addition assignment operator (+=).
function sum(range) {
if (!(range instanceof Array)) {
throw new TypeError("sum() expects an Array as it's only argument");
} return range.reduce((a,b) => a+=b);
}
Testing it:
let a = range(1,10);
let b = range(5,2);
let c = range(5,2,true);
let d = range(3,-1);
let e = range(10,10);
console.log(a); // [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ]
console.log(b); // [ 2, 3, 4, 5 ]
console.log(c); // [ 5, 4, 3, 2 ]
console.log(d); // [ -1, 0, 1, 2, 3 ]
console.log(e); // [ 10 ]
console.log(range('test', 10)); // TypeError
console.log(range(1, 'test')); // TypeError
console.log(sum(a)); // 55
console.log(sum(b)); // 14
console.log(sum(c)); // 14
console.log(sum(d)); // 5
console.log(sum(e)); // 10
console.log(sum('test')); // TypeError
here my answer, I'd glad if you give me feedback about this solution.
let arr = [];
function range(x, y) {
for (let i = x; i <= y; i++) {
arr.push(i);
}
return arr;
}
function sum(array) {
const many = array.reduce((total, number) => {
return total + number;
}, 0);
return many;
}
console.log(sum(range(1, 10)));
Related
I am trying to solve a leetcode type problem that is a practice problem that came with an upcoming code test I need to do for a job and I am having trouble with it. Can anyone help me understand whats going wrong?
I am essentially looking for the brute force option as I dont know algos/DS.
PROBLEM:
Write a function:
function solution(A);
that, given an array A of N integers, returns the smallest positive integer (greater than 0) that does not occur in A.
For example, given A = [1, 3, 6, 4, 1, 2], the function should return 5.
Given A = [1, 2, 3], the function should return 4.
Given A = [−1, −3], the function should return 1.
Write an efficient algorithm for the following assumptions:
N is an integer within the range [1..100,000];
each element of array A is an integer within the range [−1,000,000..1,000,000].
HERE IS MY SOLUTION:
function solution(A) {
let newArray = A.sort(function(a, b){return a-b})
let lowestNumber = 1
for(i=0; i < newArray.length; i++) {
if(lowestNumber > newArray[0]) {
return lowestNumber
}
if(lowestNumber == newArray[i]) {
lowestNumber = lowestNumber + 1
}
if(i = newArray.length - 1) {
return lowestNumber
}
}
}
The below snippet isnt working like I expect it to. lowestNumber isnt being increased and also the loop is exiting here I believe.
if(lowestNumber == newArray[i]) {
lowestNumber = lowestNumber + 1
Thanks for your help!
You can do this in O(N) using a Map():
First set every number in the array.
Then starting from 1 look for and return the missing number in the sequence.
function solution(arr) {
const seen = new Map();
for (let i = 0; i < arr.length; i++) {
seen.set(arr[i]);
}
for (let i = 1; i <= arr.length + 1; i++) {
if (!seen.has(i)) return i;
}
return 1;
}
console.log(solution([1, 3, 6, 4, 1, 2])); //-> 5
console.log(solution([1, 2, 3])); //-> 4
console.log(solution([-1, -3])); //-> 1
I think your > should be <, and the = in if(i = newArray.length - 1) should be ===.
And lowestNumber > newArray[0] will always be true if the array contains a negative number, so 1 will be returned.
Your effort seems careless, so you are going to have to up your game for the interview.
const integers = [5, -345, 562456, 95345, 4, 232, 1, 2, 3, 7, -457];
function solution(A) {
let newArray = A.sort((a, b) => a - b);
let lowestNumber = 1;
for (let i = 0; i < newArray.length; i++) {
const n = newArray[i];
if (n > 0) {
if (lowestNumber < n) {
return lowestNumber;
} else {
lowestNumber = n + 1;
}
}
}
return lowestNumber;
}
console.log(solution(integers));
The fastest solution
function solution(A) {
// write your code in JavaScript (Node.js 8.9.4)
if (!A) return 1;
A.sort();
if (A[A.length - 1] < 1) return 1;
const setA = new Set(A);
let length = setA.size;
for (let i = 1; i <= length; i++) {
if (!setA.has(i)) {
return i;
}
}
return length + 1;
}
I have worked same problem for nowadays, and regardless the original answer, here is my version of finding least positive number which is missing the in the array.
function findLeastPositive(array) {
const numbersSet = new Set(array);
let leastPositiveNumber = 1;
while(numbersSet.has(leastPositiveNumber)) {
leastPositiveNumber++;
}
return leastPositiveNumber;
}
let result = findLeastPositive([1,2,3,4,5,6,7,8,9,0]);
console.log(result);
result = findLeastPositive([10,11,12,13,14,15,16,17,18,19]);
console.log(result);
There are sure similar answers floating on the internet but using given array length disturbing me of which I can't explain properly why we have to create second loop starts with 1 (known the least positive number) and to N.
Using hash table (I am using Set here) for lookup table is fine idea, as in it effect to overall performance O(N) (probably initialize the Set with array) and O(1) for checking if the value in the Set or not.
Then we need to set second loop for obvious reason that checking the the smallest positive number existence, starting from 1..N range. This is the part bugged me, so I decided to go for while loop. It's obvious rather why there's a for..loop starts from 1..N on which N is the length of the array.
Here is 100% code
function solution(A) {
/**
* create new array of positive numbers in given array,
* if there sis no specific number in given array, in result array
* that index will be undefine
*/
const c = A.reduce((arr, cur) => {
if(cur > 0) arr[cur] = 1;
return arr;
} , [1] )
/**
* return first undefined index
*/
for(let i = 0; i < c.length; i++)
if(!c[i]) return i;
// otherwise return the maximum index in array
return c.length;
}
function solution(arr) {
for (let i = 1; i <= arr.length + 1; i++) {
if (!arr.includes(i)) return i;
}
return 1;
}
console.log(solution([1, 3, 6, 4, 1, 2])); //-> 5
console.log(solution([1, 2, 3])); //-> 4
console.log(solution([-1, -3])); //-> 1
var myArr = [1,2,3,4,5,6,7,8,9,10];
function even(num) {
var newArr = [];
for (var i=1; i<num.length; i++) {
if (num[i] % 2 === 0) {
newArr.push(num[i]);
}
}
return newArr;
}
console.log(even(myArr));
My function throws an exception when called. How can I rewrite or refactor the above code to return the first 5 positive numbers?
You can create it this way.
var myArr = [1,2,0,3,4,-6,5,-3,88,21,-6,5,6,7,8,9,10];
let evens = myArr.filter(x => x > 0 && x % 2 == 0).slice(0, 5);
console.log(evens)
First off, your code appears to work. Can you give an example of the error that is occurring? Second off, if you want a function that returns an array of the first n positive, even integers, you can write something like this.
function firstEven(count) {
var response = []; // Create the response list
for(var i=0;i<count;i++) { // Loop for number of even numbers you want
response.push((i + 1) * 2); // *2 skips every two numbers, and +1 shifts the number to even
}
return response
}
However, if you want to just filter out all odd numbers from an array, you can do the following.
var myArr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
var myEvens = myArr.filter(function(myNum) { // Filter runs the function for every value in the array, and (if the function returns false) it removed that value
return (myNum % 2) == 0;
});
Feel free to ask if you have any questions!
2 others differnts ways
const myArr = [1,2,3,4,-6,5,-3,88,21,-6,5,6,7,8,9,10];
const even_1 = arr => arr.filter(x=>(x>=0 && !(x&1))).slice(0,5)
const even_2 = arr =>
{
let r = []
for(x of arr)
if (x>=0 && !(x&1)) // test2 = boolean AND on bit zero
{
r.push(x);
if (r.length >= 5) break;
}
return r
}
console.log('even 1:', even_1(myArr).join(','))
console.log('even 2:', even_2(myArr).join(','))
One suggestion:
var myArr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13];
function even(numbersArray) {
var first5EvenNums = [];
for (const num of numbersArray) {
if (first5EvenNums.length >= 5) break;
if (num % 2 === 0) {
first5EvenNums.push(num);
}
}
return first5EvenNums;
}
console.log(even(myArr));
<script src="//ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>
<div id="test"></div>
<script>
var myArr = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15];
function even(num){
var newArr = [];
for (var i=1; i<num.length; i++){
if (num[i] % 2 === 0)
{
newArr.push(num[i]);
if(newArr.length == 5){
return newArr;
}
}
}
return newArr;
};
$("#test").text(even(myArr));
</script>
This return first 5 positive number in array.
I'm trying to find a better/faster algorithm that doesn't timeout when I try to find any 2 numbers in an array of numbers that add up to a sum(ex. s). I need to return the pair of numbers that adds up to sum(s) which also have the indices that appear the earliest(there maybe many other pairs). Here is my nested for loop approach.
function sum(ints, s){
let pusher = [];
let count = 1000;
for(let i = 0; i < ints.length; i++){
for(let j = i+1; j < ints.length; j++){
if(ints[i] + ints[j] === s){
if(j < count){
pusher = [ints[i],ints[j]];
count = j;
}
}
}
}
return pusher.length > 0 ? pusher : undefined ;
}
To reduce the computational complexity from O(n ^ 2) to O(n), create a Setinstead. When iterating over a number, check if the set has the value sum - num - if it does, return that pair as the result. Otherwise, put the number into the Set:
Or you could use a Set
function sum(ints, sum) {
const set = new Set();
for (const num of ints) {
const otherNum = sum - num;
if (set.has(otherNum)) {
return [num, otherNum];
} else {
set.add(num);
}
}
}
console.log(sum([3, 4, 99, -2, 55, 66, -3], 1));
console.log(sum([1, 9, 15, 2, 4, 7, 5], 6));
I worked on a problem where you are given an array of numbers and a target sum, and it's your job to find a pair of numbers that sum up to the target number. Here was my solution using simple nested for loops:
function findPairForSum(integers, target) {
var output = [];
for (var i = 0; i < integers.length; i++) {
for (var j = 0; j < integers.length; j++) {
if (i !== j && integers[i] + integers[j] === target) {
output.push(integers[i], integers[j]);
return output;
}
}
}
return 'not possible';
}
findPairForSum([3, 34, 4, 12, 5, 2], 9); // --> [4, 5]
My question is, is there a cleaner way to write this solution using higher order functions (perhaps forEach?)
Here was my attempt to use forEach:
function findPairForSum(integers, target) {
var output = [];
integers.forEach(function(firstNum) {
integers.forEach(function(secondNum) {
if (firstNum + secondNum === target) {
output.push(firstNum, secondNum);
}
})
})
if (output === []) {
return 'not possible';
}
return output;
}
findPairForSum([3, 34, 4, 12, 5, 2], 9); // --> [ 4, 5, 5, 4 ]
I tried putting a return after the two pushes, but it did not return anything. So instead, I put the return at the very end.
Why won't it return after the initial two pushes? I want it to stop right there, and only push the two numbers. Instead, by putting the return at the end, it pushed 4 numbers. It should be [4,5] but I got something like [4,5,5,4].
Any advice and help would be much appreciated!
Assume we have the following set of numbers, and we must find a subset of 2 numbers whose sum is 9:
Numbers: 4, 5, 6
Your current code iterates both with i and j from 0 to length. This means that the following iterations match the condition:
Indices: 0, 1, 2
Numbers: 4, 5, 6 // (i) (j)
---------------- // ↓ ↓
i j // Numbers[0] + Numbers[1] === 9
j i // Numbers[1] + Numbers[0] === 9
As you can see, the numbers 4 and 5 are matched twice, in 2 iterations:
i === 0 && j === 1
i === 1 && j === 0
You can avoid this by making sure one simple condition is met:
j must at all times be greater than i
This condition can be met met by initializing j with i + 1 in the inner for loop:
for (var i = 0; i < integers.length; i++) {
for (var j = i + 1; j < integers.length; j++) {
// ...
}
}
This way, j can never be 0 when i is 1, because the inner for-loop will run to completion before i is ever incremented once more. Once that happens, a brand new inner for-loop is created, in which j is again set to i + 1. The following diagram is the result:
Indices: 0, 1, 2
Numbers: 4, 5, 6
----------------
i j
X i // ← j can never be 0 if (i === 1),
// so the same set is never evaluated twice.
In other words, only the following combinations for i and j are checked at most:
Indices: 0, 1, 2
----------------
i j
i j
i j
is there a cleaner way to write this solution using higher order functions (perhaps forEach?)
A for loop is actually a fine solution for your use-case. They allow you to break early - after the first time you find a valid pair of numbers. forEach or other array iterator functions on the other hand will always continue until all set indices are visited.
You are actually breaking early in your first example with the statement return output;
When you use forEach on a set of numbers with multiple valid sets, you'll always get back all numbers involved:
Indices: 0, 1, 2, 3
Numbers: 4, 5, 6, 3 // (i) (j)
------------------- // ↓ ↓
i j // Numbers[0] + Numbers[1] === 4 + 5 === 9
i j // Numbers[2] + Numbers[3] === 6 + 3 === 9
forEach, map, reduce and the like do not allow you to break early. The following snippet demonstrates this issue of the diagram above:
function findPairForSum(integers, target) {
var output = [];
integers.forEach(function(firstNum, i) {
// slice(i + 1) has the same effect as for (var j = i + 1; ...)
integers.slice(i + 1).forEach(function(secondNum, j) {
if (firstNum + secondNum === target) {
// There is no way here to stop the iteration of either
// forEach call... T_T
output.push(firstNum, secondNum);
}
});
})
if (output.length) {
return output;
}
return 'not possible';
}
console.log(findPairForSum([4, 5, 6, 3], 9)); // --> [4, 5, 6, 3]
This is why I highly recommend sticking with the for loops for this specific use case. With for loop you can simply return as you already did as soon as you encounter a valid set of numbers:
function findPairForSum(integers, target) {
for (var i = 0; i < integers.length; i++) {
for (var j = i + 1; j < integers.length; j++) {
if (integers[i] + integers[j] === target) {
return [integers[i], integers[j]];
}
}
}
return 'not possible';
}
console.log(findPairForSum([4, 5, 6, 3], 9)); // --> [4, 5]
This could be your solution:
function findPairForSum(arr, sum) {
var pairs = [];
arr.forEach(n1 => {
var n2 = arr.find(n2 => n1 + n2 == sum)
if (n2) pairs.push([n1, n2]);
});
return pairs;
}
var sums = findPairForSum([3, 34, 4, 12, 6, 2], 9);
console.log(sums)
The problem is, you iterate from the start of the array for the inner loop. You could use a copy which starts at the index of the outer loop plus one and exit early on a found value.
But this does not solves the problem with multiple pairs. The result is simply wrong.
function findPairForSum(integers, target) {
var output = [];
integers.forEach(function(firstNum, i) {
integers.slice(i + 1).some(function(secondNum) {
if (firstNum + secondNum === target) {
output.push(firstNum, secondNum);
return true;
}
});
});
return output.length && output || 'not possible';
}
// console.log(findPairForSum([3, 34, 4, 12, 5, 2], 9));
console.log(findPairForSum([3, 34, 4, 4, 12, 5, 2, 4, 5], 9));
For a solution, you need to remember which pairs are used. This approach works with only one loop and a hash table for counting missing values.
If a pair is found, the counter is decremented and the two values are pushed to the result set.
function findPairForSum(integers, target) {
var hash = Object.create(null),
output = [];
integers.forEach(function(value) {
if (hash[value]) {
output.push(target - value, value);
hash[value]--;
return;
}
hash[target - value] = (hash[target - value] || 0) + 1;
});
return output.length && output || 'not possible';
}
console.log(findPairForSum([3, 34, 4, 4, 12, 5, 2, 4, 5], 9));
This is expected, since you didn't compare the indexes.
This inner array should only loop through the indexes which larger than the outer index.
You can achieve this by using the 2nd parameter, index, in forEach's callback function:
const ints = [3, 34, 4, 12, 5, 6, 2];
function findPairForSum(integers, target) {
let result;
integers.forEach((val1, idx1) => {
integers.forEach((val2, idx2) => {
if (idx1 < idx2 && val1 + val2 === target) {
result = [val1, val2];
}
})
})
return result;
}
console.log(findPairForSum(ints, 9));
Use can reduce your array into another which has sum equals target value:
const ints = [3, 34, 4, 12, 6, 2];
const value = 9;
const resp = ints.reduce((acc, ele, idx, self) => {
let found = self.find(x => x + ele == value)
return found ? [found, ele] : acc;
}, []);
console.log(resp); // [3, 6]
You can use Array.prototype.some which will stop execution as soon as the condition becomes true. See below code.
function findPairForSum(arr, sum) {
var pairs = [];
arr.some(n1 => {
var n2 = arr.find(n2 => n1 + n2 == sum)
if (n2) {
pairs.push(n1, n2); return true;
};
return false;
});
return pairs.length > 0 ? pairs : "not possible";
}
console.log(findPairForSum([3, 34, 4, 12, 7, 2], 9));
I am trying to solve this challenge Seek and Destroy. I can't figure out what is wrong. Any help ?
Seek and Destroy
You will be provided with an initial array (the first argument in the destroyer function), followed by one or more arguments. Remove all elements from the initial array that are of the same value as these arguments.
This is the initial code below:
function destroyer(arr) {
// Remove all the values
return arr;
}
destroyer([1, 2, 3, 1, 2, 3], 2, 3);
This is my Code below:
function destroyer(arr) {
var letsDestroyThis = [];
var i =1 ; while (i<arguments.length) {
letsDestroyThis.push(arguments[i]);
i++;
}
for(var j=0 ; j< arguments[0].length; j++) {
for (var k= 0; k< letsDestroyThis.length; k++) {
if(arguments[0][j] === letsDestroyThis[k]){
arguments[0].splice(j, 1);
}
}
}
return arguments[0];
}
destroyer([2, 3, 2, 3], 2, 3);
Thanks in Advance!
You can create an array of all values that are supposed to be removed. Then use Array.filter to filter out these values.
Note: Array.splice will change original array.
function destroyer() {
var arr = arguments[0];
var params = [];
// Create array of all elements to be removed
for (var k = 1; k < arguments.length; k++)
params.push(arguments[k]);
// return all not matching values
return arr.filter(function(item) {
return params.indexOf(item) < 0;
});
}
console.log(destroyer([1, 2, 3, 1, 2, 3], 2, 3));
function destroyer(arr) {
/* Put all arguments in an array using spread operator and remove elements
starting from 1 using slice intead of splice so as not to mutate the initial array */
const args = [...arguments].slice(1);
/* Check whether arguments include elements from an array and return all that
do not include(false) */
return arr.filter(el => !args.includes(el));
}
console.log(destroyer([1, 2, 3, 1, 2, 3], 2, 3));
This worked for me:
function destroyer(arr) {
// Remove all the values
var args = Array.from(arguments);
var filter = [];
for (i = 0; i < args[0].length; i++) {
for (j = 1; j < args.length; j++) {
if (args[0][i] === args[j]) {
delete args[0][i];
}
}
}
return args[0].filter(function(x) {
return Boolean(x);
});
}
console.log(
destroyer([1, 2, 3, 1, 2, 3], 2, 3)
);
//two ways of resolving the Seek and Destroy challenge on the FreeCodeCamp
//I was trying to simplify this code, please post your solutions, simplifying the code
//as much has its possible
function destroyer1 (arr){
//get array from arguments
var args = Array.prototype.slice.call(arguments);
args.splice(0,1);
for (var i = 0; i < arr.length; i++){
for(var j = 0; j < args.length; j++){
if(arr[i]===args[j]){
delete arr[i];
}
}
}
return arr.filter(function(value){
return Boolean(value);
});
}
//--------------------------------------
function destroyer(arr) {
// Remove all the values
//Get values from arguments of the function to an array, index 0(arr[0] will be "arr",
//rest of indexes will be rest of arguments.
var args = Array.from(arguments);
for (var i = 0 ; i < args[0].length; i++){
for (var j = 1; j < args.length; j++){
if(args[0][i] === args[j]){
delete args[0][i];
}
}
}
return args[0].filter(function(value){
return Boolean(value);
});
}
console.log(destroyer([1, 2, 3, 1, 2, 3], 2, 3));
console.log(destroyer1([1,6,3,9,8,1,1], 3,1));
This is my Code:
function destroyer(arr) {
var argsBeRemove = [...arguments];
argsBeRemove.shift();
return arr.filter(val => {
return argsBeRemove.indexOf(val) == -1;
});
}
console.log(destroyer([1, 2, 3, 1, 2, 3], 2, 3));
Here is my version of Seek and Destroy. I assume that there are no zero elements in input (that assumption allows to pass the challenge). But that way I can make found elements equal zero and then just filter them out. It is pretty straight forward and no index mess when deleting elements in for loops.
function destroyer(arr) {
// Remove all the values
var args = Array.prototype.slice.call(arguments);
var temp = [];
temp = arguments[0].slice();
for (j = 1; j < args.length; j++) {
for (i = 0; i < arguments[0].length; i++) {
if (arguments[0][i] == arguments[j]) {
temp[i] = 0;
}
}
}
function isZero(value) {
return value !== 0;
}
var filtered = temp.filter(isZero);
return filtered;
}
console.log(destroyer([1, 2, 3, 1, 2, 3], 2, 3));
function destroyer(arr) {
var args = Array.prototype.slice.call(arguments, 1);
return arr.filter(destroyNum);
function destroyNum(element) {
return !args.includes(element);
}
}
console.log(destroyer([1, 2, 3, 1, 2, 3], 2, 3));
Give this a shot, it is way less convoluted:
function destroyer(arr) {
// arr1 is equal to the array inside arr
var arr1 = arr.slice(arguments);
// arr2 becomes an array with the arguments 2 & 3
var arr2 = Array.prototype.slice.call(arguments, 1);
// this function compares the two and returns an array with elements not equal to the arguments
return arr1.concat(arr2).filter(function(item) {
return !arr1.includes(item) || !arr2.includes(item)
})
}
destroyer([1, 2, 3, 1, 2, 3], 2, 3);
You will be provided with an initial array (the first argument in the destroyer function), followed by one or more arguments. Remove all elements from the initial array that are of the same value as these arguments.
The accepted solution returns a new array, instead of removing the elements from the existing array.
This can be achieved efficiently by iterating the array in reverse and removing any elements matching any of the filter arguments.
function destroy(original, ...matches) {
if('length' in original) {
let index = original.length
while(--index > -1) {
if(matches.includes(original[index])) {
original.splice(index, 1)
}
}
}
return original;
}
const original = [1, 2, 3, 1, 2, 3]
destroy(original, 2, 3)
console.log(original);
My answer is similar to previous one, but I didn't use indexOf. Instead of that I checked the values in cycle, but compiler gives me a warning to not to declare function in cycle.
function destroyer(arr) {
// Remove all the values
var temp = [];
for (var i = 1; i < arguments.length; i++) {
temp.push(arguments[i]);
arr = arguments[0].filter(function(value) {
return ( value !== temp[i - 1]) ;
});
}
return arr;
}
destroyer([1, 2, 3, 1, 2, 3], 2, 3);
We can get the arguments behind the array, which are the number required to be removed and store them to a list. Then, we can just use a filter to filter out the numbers that needed to be removed.
function destroyer(arr) {
let removeList=[...arguments].slice(1);
return arr.filter(e=>removeList.indexOf(e)===-1);
}
I know isn't the shortest way to do it, but i think is the more simple to understand in an intermediate level.
function destroyer(arr, ...elements) {
var i =0;
while(i<=arr.length){ //for each element into array
for(let j =0; j<elements.length; j++){ //foreach "elements"
if(arr[i]==elements[j]){ // Compare element arr==element
arr.splice(i,1); //If are equal delete from arr
i--; //Check again the same position
j=0;
break; //Stop for loop
}
}
i++;
}
return arr;
}
console.log(destroyer(["possum", "trollo", 12, "safari", "hotdog", 92, 65, "grandma", "bugati", "trojan", "yacht"], "yacht", "possum", "trollo", "safari", "hotdog", "grandma", "bugati", "trojan"));
console.log(destroyer([1, 2, 3, 5, 1, 2, 3], 2, 3));
function destroyer(arr) {
let newArray = Array.from(arguments).splice(1)
return arr.filter(item => !(newArray.includes(item)))
}