So this is a bit of a newbie troubleshooting question. I am doing an exercise of freecodecamp, and I am having an issue parsing the input to my function. It's short, and I think I can cut to the chase if I just show you the code:
function destroyer(arr) {
// Remove all the values
console.log("---");
console.log("arr: " + arr);
var args = Array.from(arr);
console.log(args);
var in_i = arr[0];
return in_i.filter(function (x) {
if (args.indexOf(x) !== -1) {
return true;
} else {
return false;
}
});
}
destroyer([1, 2, 3, 1, 2, 3], 2, 3);
which gives me in the console (and I think this is the strange part):
---
arr: 1,2,3,1,2,3
[1, 2, 3, 1, 2, 3]
Clearly I'm not understanding something about arguments objects, or else something is broken. In my experience, the latter is exceedingly uncommon. I would have expected the Array.from(arr) to give an array object: [[1, 2, 3, 1, 2, 3], 2, 3].
The function function destroyer(arr) accepts only 1 parameter in the function destroyer which is an array [1, 2, 3, 1, 2, 3] and ignore the other arguments 2, 3. So, the arr is [1, 2, 3, 1, 2, 3].
If you need to access all the parameters passed to the function, then you can make use of arguments object which is an array like object. arguments would point to the array [[1, 2, 3, 1, 2, 3], 2, 3]. Following code should display the Arguments passed.
function destroyer(arr, param2, param3) {
// Remove all the values
console.log(arguments);
}
destroyer([1, 2, 3, 1, 2, 3], 2, 3);
If your function takes 3 parameters as shown below, param2, param3 have been added, then you can access the value 2, 3 inside your function.
function destroyer(arr, param2, param3) {
// Remove all the values
console.log("---");
console.log("arr: " + arr);
var args = Array.from(arr);
console.log(args);
var in_i = arr[0];
return in_i.filter(function (x) {
if (args.indexOf(x) !== -1) {
return true;
} else {
return false;
}
});
}
destroyer([1, 2, 3, 1, 2, 3], 2, 3);
In fact, the part that confused me was that on MDN, the use of the arguments variable was not just illustrative, it's a built-in variable. After #Agalo pointed out that the values I was getting on the console were just the array, it clicked for me.
The solution was to access the extra arguments through the built-in arguments object which automatically has the (reserved) name arguments. Code is like so (for completeness, I should note that I also had false and true switched in the return statements):
function destroyer(arr) {
// Remove all the values
var args_l = arguments.length;
var args = Array.from(arguments);
console.log(args);
var in_i = args.shift();
return in_i.filter(function (x) {
if (args.indexOf(x) !== -1) {
return false;
} else {
return true;
}
});
}
destroyer([1, 2, 3, 1, 2, 3], 2, 3);
To riff off of Agalo, you'll note you don't actually need the param2, param3 arguments in the function definition to get the exact same output:
function destroyer(arr) {
// Remove all the values
console.log(arguments);
}
destroyer([1, 2, 3, 1, 2, 3], 2, 3);
At the risk of putting too fine a point on it:
function args_tester(a) {
console.log("a: " + a);
console.log("arguments: " + arguments);
console.log("arguments_as_array: " + Array.from(arguments));
for (var i = 0; i < arguments.length; i++) {
console.log(arguments[i]);
}
}
args_tester("a", "b", "c");
Related
I need to remove the first item in the arguments object so that my let args variable equals to all the following arguments.
How can I do it?
function destroyer(arr) {
let myArr = arguments[0];
let args = arguments;
}
destroyer([1, 2, 3, 1, 2, 3], 2, 3);
Use slice to retrieve the arguments past the first, and use rest parameters instead of a single arr in your function argument, if you can - many linters recommend against using arguments, and using that keyword is not necessary here:
function destroyer(...args) {
const otherArgs = args.slice(1);
console.log('length: ' + otherArgs.length, 'items: ' + otherArgs);
}
destroyer([1, 2, 3, 1, 2, 3], 2, 3);
If you want a reference to the first argument as well, use rest parameters after collecting the first arr into a variable:
function destroyer(arr, ...otherArgs) {
console.log('arr: ' + arr);
console.log('length: ' + otherArgs.length, 'items: ' + otherArgs);
}
destroyer([1, 2, 3, 1, 2, 3], 2, 3);
Simplest way:
function destroyer(...arr) {
arr.shift();
console.log( arr ); // 2,3
}
destroyer([1, 2, 3, 1, 2, 3], 2, 3);
In the code below I expected the result of destroyer([1, 2, 3, 1, 2, 3], 2, 3); would be [1,1].
But the result pops out to be [1,2,3,1,2,3].
Where am I going wrong?
function destroyer(arr) {
function hlp(x) {
for(var i=1; i<arguments.length ; i++) {
if(x == arguments[i]) return false;
}
return true;
}
return arr.filter(hlp);
}
console.log(destroyer([1, 2, 3, 1, 2, 3], 2, 3));
You can use ES6 rest parameter syntax and check if array includes any of those parameters using include()
function destroyer(arr, ...rest) {
function hlp(e) {
return !rest.includes(e)
}
return arr.filter(hlp);
}
console.log(destroyer([1, 2, 3, 1, 2, 3], 2, 3));
If you want to use for loop and arguments your code should look like this.
function destroyer(arr) {
var arg = arguments
function hlp(x) {
for (var i = 1; i < arg.length; i++) {
if (x == arg[i]) return false;
}
return true;
}
return arg[0].filter(hlp);
}
console.log(destroyer([1, 2, 3, 1, 2, 3], 2, 3));
You've defined destroyer to only accept one argument, while you're passing in more than one. arguments is undefined, and iterating in a function passed to Array.filter() isn't a good idea. Array.filter() checks every element for you. Not that it would work in your code, but if it would, it would be better to just return x == arguments[i] instead of checking whether it's true or false. If you return x == arguments[i] you're actually returning a boolean. An example of that is where I in the code below return exclude.indexOf(i) == -1;. Try the following approach instead:
function destroyer(arr, exclude) {
return arr.filter(function(i) {
return exclude.indexOf(i) == -1;
});
}
console.log(destroyer([1, 2, 3, 1, 2, 3], [2, 3]));
Solved in two ways:
1st:
function destroyer(arr) {
function hlp(x) {
for(var i=1; i<destroyer.arguments.length ; i++) {
if(x == destroyer.arguments[i]) return false;
}
return true;
}
return arr.filter(hlp);
}
console.log(destroyer([1, 2, 3, 1, 2, 3], 2, 3));
2nd
Look to the solution posted by #Nenad Vracar
This is the code I have been given. I looked around and I don't quite understand.
This is my question function destroyer accepts one parameter an array but when its being called 3 parameters are sent: an array and 2 integers.
How can I access the two integer parameters in the function if they haven't been passed? Is there something in Javascript that would allow this?
function destroyer(arr) {
// Remove all the value;
return arr;
}
destroyer([1, 2, 3, 1, 2, 3], 2, 3);
You can use arguments variable in your function to get a list of passed arguments.
// ES5
function destroyer(arr) {
var pieces = Array.prototype.splice.call(arguments, 1);
var i = 0;
while (arr[i]) {
-1 === pieces.indexOf(arr[i]) ? i++ : arr.splice(i, 1);
}
return arr;
}
// ES6
function destroyer2(arr, ...pieces) {
var i = 0;
while (arr[i]) {
-1 === pieces.indexOf(arr[i]) ? i++ : arr.splice(i, 1);
}
return arr;
}
console.log(JSON.stringify(destroyer([1, 2, 3, 1, 2, 3], 3, 1)));
console.log(JSON.stringify(destroyer2([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.
I've these instructions:
destroyer([1, 2, 3, 1, 2, 3], 2, 3) should return [1, 1].
destroyer([1, 2, 3, 5, 1, 2, 3], 2, 3) should return [1, 5, 1].
destroyer([3, 5, 1, 2, 2], 2, 3, 5) should return [1].
destroyer([2, 3, 2, 3], 2, 3) should return [].
destroyer(["tree", "hamburger", 53], "tree", 53) should return ["hamburger"].
I've found code:
function destroyer(arr) {
var args = Array.prototype.slice.call(arguments);
args.splice(0,1);
return arr.filter(function(element) {
return args.indexOf(element) === -1;
});
}
My questions:
Can you explain this code in English, please?
Can you give a shortcut code for above challenge? please.
I've done this challenge using filter function, though t is recommended to use also 'indexOf' in order to compare value in array by the value to filter with.
````
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);
````
function destroyer(arr) {
var args = arr.slice.call(arguments);
args.splice(0,1);
return arr.filter(function(element) {
return args.indexOf(element) === -1;
});
}
line 1 declares the overall function used for the challenge
line 2 converts the arguments of arr into a array variable named args, although this method doesn't work when optimizing in certain javascript platforms (optimization is basically what you're trying to do with your second question)
line 3 removes zero (0) and one (1) from args
lines 4 and 5 return the final result (true/false) of filtering arr for falsy and truthy by seeing whether or not an element of arg is present in arr, returning -1 if not and the element's location in arr if true
this is actually relatively optimized; there is much more more-optimized code but oftentimes it is only viable on certain javascript platforms (mozilla javascript, etc.)
There is 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.
Here is my code, but I am unable to solve the problem.
function destroyer(arr) {
// First I have converted the whole input into an array including the arguments
var args = Array.prototype.slice.call(arguments);
var abc=args.splice(0,1);//Here I have taken out the array part i.e[1,2,3,1,2,3] and also now args contain 2,3 only
function des(abc){
for(var i=0;i<abc.length;i++){//I tried to check it for whole length of abc array
if(args.indexOf(abc)===-1){
return true; //This should return elements of [1,2,3,1,2,3] which are not equal to 2,3 i.e [1,1] but for string inputs it is working correctly.How to do for these numbers?
}
}
}
return arr.filter(des); //but this filter function is returning empty.How to solve my problem??
}
destroyer([1, 2, 3, 1, 2, 3], 2, 3);
For destroyer(["tree", "hamburger", 53], "tree", 53) the code is giving output ["hamburger"],which is working fine.
But for destroyer([1, 2, 3, 1, 2, 3], 2, 3); code is giving no output.
You can use Array.filter. Following example depicts the same
Also destroyer([1, 2, 3, 1, 2, 3], 2, 3); in this call, [1, 2, 3, 1, 2, 3] is first argument, 2 is second and 3 is third. So arr will have be [1, 2, 3, 1, 2, 3] and not [1, 2, 3, 1, 2, 3], 2, 3
function removeElementFromArray(arr,num){
var _temp = arr.filter(function(item){
return (item !== num);
});
return _temp;
}
(function main(){
var arr = [1,1,1,2,4,3,2,4,5,4,3,1,4,5,2];
var result = removeElementFromArray(arr,1);
var result1 = removeElementFromArray(arr,3);
console.log(result, result1);
})()
Try this:
function destroyer(arr) {
var args = Array.prototype.slice.call(arguments, 1);
function des(abc){
return args.indexOf(abc) === -1;
}
return arr.filter(des);
}
var result = destroyer([1, 2, 3, 1, 2, 3], 2, 3);
document.getElementById('output').innerHTML = JSON.stringify(result);
<pre id="output"></pre>
Lodash has without method that can be useful.
link to doc.
From lodash docs:
_.without(array, [values])
Creates an array excluding all provided values using SameValueZero for
equality comparisons.
Example:
_.without([1, 2, 1, 3], 1, 2);
// → [3]
This should work for you:
function destroyer(arr) {
var args = Array.prototype.slice.call(arguments);
var abc = args.splice(0, 1);
function des(value) {
// you don't need loop here, just check if given value is in args array
return args.indexOf(value) === -1;
}
// splice returns array of deleted elements so that your first argument is abc[0]
return abc[0].filter(des);
}
var result = destroyer([1, 2, 3, 1, 2, 3], 2, 3);
console.log(result);
Try this easy code:
function destroyer(arr) {
/* Put all arguments in an array using spread operator and remove elements
starting from 1 */
const args = [...arguments].splice(1);
/* Check whether arguments include elements from an array and return all that
do not include(false) */
return arr.filter(el => !args.includes(el));
}
destroyer([1, 2, 3, 1, 2, 3], 2, 3); // [1, 1]