Javascript arguments inside a .filter method - javascript

I'm working on a problem, where I am provided with an initial array (the first argument in the destroyer function), followed by one or more arguments. I need to remove all elements from the initial array that are of the same value as these arguments.
The function only takes 1 argument (the array), and there can be any number of additional arguments, which I can select as "arguments[index]".
Here is my code up to now:
function destroyer(arr) {
newArr= [ ];
newArr = arr.filter(function(x){
return x !== arguments[2]; //argumets[2] is equal to 3
});
return newArr;
}
destroyer([1, 2, 3, 1, 2, 3], 2, 3);
// => returns [1, 2, 3, 1, 2, 3];
BUT if i enter 3, instead of arguments[2], the function returns [1,2,1,2].
What is going on?
Additionally, how can I loop through the code to test all other arguments, if I can't have a function in a loop?

arguments refers to the arguments of the second function
you can do something like this
function destroyer(arr) {
newArr= [ ];
var args = arguments;
newArr = arr.filter(function(x){
return x !== args[2];
});
return newArr;
}
destroyer([1, 2, 3, 1, 2, 3], 2, 3);

First, make a reference to the top destroyer argument. Then use that inside your filter function.
function destroyer(arr) {
newArr= [ ]; var args = arguments;
newArr = arr.filter(function(x){
return x !== args[2]; //destoryer's arguments[2] is equal to 3
});
return newArr;
}
destroyer([1, 2, 3, 1, 2, 3], 2, 3);

Related

Pass an array and further arguments into a function. How?

I have a function which takes an array and further arguments like this:
function arrayandmore([1, 2, 3], 2, 3)
I need to return the array ([1, 2, 3]) without those elements which equals the arguments coming behind the array. So in this case, the returned array would be:
([1]).
One of my approaches is:
function destroyer(arr) {
var args = Array.from(arguments);
var i = 0;
while (i < args.length) {
var result = args[0].filter(word => word !== args[i]);
i++;
}
console.log(result);
}
destroyer([1, 1, 3, 4], 1, 3);
Console returns:
[ 1, 1, 4 ]
I don't understand, why it returns one too - I don't understand, why it does not work.
It is the same with using splice.
function destroyer(arr) {
var args = Array.from(arguments);
var quant = args.length - 1;
for (var i = 1; i <= quant; i++) {
if (arr.indexOf(args[i]) !== -1) {
arr = arr.splice(arr.indexOf(args[i]));
}
console.log(arr);
}
}
destroyer([1, 1, 3, 4], 1, 3);
I think, both ways should work. But I don't figure out why they don't.
Your while won't work because result is being overwritten in every loop. So, it only ever removes the last parameter to the destroyer function
You can use the rest parameter syntax to separate the array and the items to be removed.
Then use filter and includes like this:
function destroyer(arr, ...toRemove) {
return arr.filter(a => !toRemove.includes(a))
}
console.log(destroyer([1, 1, 3, 4, 5], 1, 3))

How is the 'apply ' method executed under the hood?

I have not understood the apply method in Javascript. From what I understood was the first parameter in the apply will be the desired value for the key word this, and the extra parameter would apply to the function the apply borrowed. I am still not sure how this apply method under the hood. How can the result be [1, 2, 3, 4, 5, 6, 7, 8]
var flattenedArray = [[1,2],[3,4,5,6], 7, 8]
[].concat.apply([],flattenedArray)
Could anyone help me how it actually works on this scenerio, please. Thanks
The result [1, 2, 3, 4, 5, 6, 7, 8] is not the value of Function#apply, but the function Array#concat.
apply only calls the function on the explicitly bound context and optionally takes parameters as array, which will be passed to the function.
When you pass [[1,2],[3,4,5,6], 7, 8] to the function apply it gets the inner items (the outer which keeps the inner items is considered to be the type of the 2nd parameter of apply, which is an array, so why it gets the inner items one by one and omit the outer array) which are [1,2] , [3,4,5,6], 7 and 8 to the function concat.
See the example. The below two calls of concat are identical.
const flattenedArray = [[1,2],[3,4,5,6], 7, 8];
const first = [].concat.apply([],flattenedArray);
console.log(first);
const second = [].concat([1,2], [3,4,5,6], 7, 8);
console.log(second);
var flattenedArray = [[1,2],[3,4,5,6], 7, 8]
[].concat.apply([],flattenedArray)
// [].concat.apply([],flattenedArray)
var concat = [].concat // ^^^^^^^^^
var me = [] // ^^
// [[1,2],[3,4,5,6], 7, 8]
var arg0 = [1,2] // ^^^^^
var arg1 = [3,4,5,6] // ^^^^^^^^^
var arg2 = 7 // ^
var arg3 = 8 // ^
me.concat = concat
var res = me.concat(arg0, arg1, arg2, arg3)
delete me.concat
console.log(res)
function concat(...args) {
var res = []
for (var x of this) {
res.push(x)
}
for (var arg of args) {
if (arg instanceof Array) {
for (var x of arg) {
res.push(x)
}
} else {
res.push(arg)
}
}
return res
}
console.log(concat.apply([], [[1,2], [3,4,5,6], 7, 8]))

JavaScript - filter through an array with arguments using for loop

I am trying to use the filter method on an array to loop through the array based on a variable number of arguments.
Below is my attempt at this:
function destroyer(arr) {
var argArr = arr.slice.call(arguments, 1);
var filteredArray = arr.filter(function(val) {
for (var i = 0; i < argArr.length; i++) {
return val != argArr[i];
};
});
console.log(filteredArray);
}
destroyer([1, 2, 3, 1, 2, 3], 2, 3);
When I do this, only the first element of the arguments array is disposed of. This therefore returns:
[1, 3, 1, 3]
I have found a few examples online of possible ways to resolve this but they are vastly different from what I understand just yet. Is there any way to get mine to work, or even understand why the additional elements of the arguments array are not being called.
If you use ES6 you can do it with rest operator and Array#includes function
function destroyer(arr, ...params){
return arr.filter(item => !params.includes(item));
}
console.log(destroyer([1, 2, 3, 1, 2, 3], 2, 3));
With your logic you can do like this. If val is equal to the current argArr's item then return false, if nothing was found after the loop: return true
function destroyer(arr) {
var argArr = Array.prototype.slice.call(arguments, 1);
var filteredArray = arr.filter(function(val) {
for (var i = 0; i < argArr.length; i++) {
if(val === argArr[i]){
return false;
}
};
return true;
});
console.log(filteredArray);
}
destroyer([1, 2, 3, 1, 2, 3], 2, 3);
Because with your code you always test if current element in filter is equal or not equal to second parameter in function which is 2 and return true/false. Instead you can use indexOf to test if current element in filter is inside arguments array.
function destroyer(arr) {
var argArr = arr.slice.call(arguments, 1);
var filteredArray = arr.filter(function(val) {
return argArr.indexOf(val) == -1
});
console.log(filteredArray);
}
destroyer([1, 2, 3, 1, 2, 3], 2, 3);
Problem is in your this line
return val != argArr[i];
Change logic like this , it will avoid to do extra looping also .
function destroyer(arr) {
var argArr = arr.slice.call(arguments, 1); debugger
var filteredArray = arr.filter(function(val) {
return !(argArr.indexOf(val) >= 0);
});
console.log(filteredArray);
}
destroyer([1, 2, 3, 1, 2, 3], 2, 3);

How to pass values to filter and values to use as a condition with the Filter method of Javascript?

I'm trying to Pass the values [1, 2, 3, 1, 2, 3] to be removed using the funcion "destroyer" and the values 2, 3 (or even more values ex: 1,3,5.) to be removed from the previous array. Always the first part is an array to remove from and followed by numbers to remove from the array
Here you have the code that I have to solve:
function destroyer(arr) {
// Remove all the values
return arr;
}
destroyer([1, 2, 3, 1, 2, 3], 2, 3);
Try this approach. It uses the spread operator and the includes() function
... - is a spread operator
function destroyer(arr, ...items) {
return arr.filter(i => !items.includes(i));
}
let arr = destroyer([1, 2, 3, 1, 2, 3], 2, 3);
console.log(arr);
You can access all parameters passed to a function using arguments variable. Note, this is an array like object but not an array, so you will have to convert it to array. When you do that, your arr will be the first value as even that is a part of parameters. You can use .slice(1) to get all values from second element.
ES5
function destroyer(arr) {
var args = [].slice.call(arguments,1);
return arr.filter(function(val){
return args.indexOf(val) < 0
})
}
console.log(destroyer([1, 2, 3, 1, 2, 3], 2, 3));
ES6
function destroyer(arr) {
var args = Array.from(arguments).slice(1);
return arr.filter(x=>!args.includes(x));
}
console.log(destroyer([1, 2, 3, 1, 2, 3], 2, 3));

Scope leak between arrays inside and outside of function scope?

I'm calling a function inside of my script main
function func(a) {
var idx;
a=a.sort();
for (idx = 0; idx < a.length + 1; idx += 1) {
if (a.indexOf(idx) === -1) {
return idx;
}
}
return 0;
}
var array = [2,1,0];
var b = func(array);
console.log(array);
The function argument (a) is an array that is being passed to the func function.
When I try to access the array in the main body of the program after calling this function it's sorted.
Does node.js link the scope between the array passed to the 'func' function and the array that was passed to it?
After calling this code, array is sorted. Why is that?
This is even true if I declare a new variable, b inside the function scope.
function func(a) {
var idx, b;
b = a;
b = b.sort();
for (idx = 0; idx < a.length + 1; idx += 1) {
if (a.indexOf(idx) === -1) {
return idx;
}
}
return 0;
}
var array = [2,1,0];
var b = func(array);
console.log(array);
The above code has the same issue.
It's not a scope leak but a twofold reason for what is happening:
because sort directly modifies the array it is applied on (while also returning it)
functions in JavaScript work with pass by reference for objects
For reason #1 look at this simple example:
var a = [3,4,1,2];
a; // [3, 4, 1, 2]
a.sort(); // [1, 2, 3, 4]
a; // [1, 2, 3, 4]
As you can see it returns the sorted array which is nothing more than the array itself that has been modified by the sort.
For reason #2 look at this simple example:
function foo(a) { a.push('hello'); }
var arr = [1,2,3,4];
arr; // [1, 2, 3, 4]
foo(arr); // undefined
arr; // [1, 2, 3, 4, "hello"]
So combining those two reasons you can see that you are passing a reference to the array into the function and then directly modifying it with a sort.
If you want to do the same thing without modifying the original array you could use Array.prototype.slice() which returns a shallow copy of the original array.
var a = [3,4,1,2];
var arr = a.slice();
a; // [3, 4, 1, 2]
arr; // [3, 4, 1, 2]
arr.sort(); // [1, 2, 3, 4]
arr; // [1, 2, 3, 4]
a; // [3, 4, 1, 2]

Categories

Resources