Removing the specific arguments - javascript

I tried to remove some words according to the passing variable.
However, I wrote two versions of code which have minor different!
And they resulted in different kinds of output which I don't understand why!
So I need u guys help, and big big thanks for u guys!
This function will be accepting the different numbers of variables,
which might be ( [arr],1,2 ) or ( [arr],1,2,8,9...) etc,
and remove the the variable in the first array according to the passing numbers.
For example: destroyer ( [1, 2, 3, 4], 2, 3 ) --> output should be [1,4]
And here is my code. ( Notice the minor difference with bold fonts! )
function destroyer(arr) {
for ( var i = 1; i < arguments.length; i++ ){
arr = arguments[0].filter(function(value){
if( value == arguments[i]){
return false;
}else{
return true;
}
});
}
return arr;
}
destroyer([1, 2, 3, 1, 2, 3], 2, 3);
The output will be [1,2,3,1,2,3], which means value == arguments[i] doesn't work. However,
function destroyer(arr) {
for ( var i = 1; i < arguments.length; i++ ){
filter = arguments[i];
arr = arguments[0].filter(function(value){
if( value == filter){
return false;
}else{
return true;
}
});
}
return arr;
}
destroyer([1, 2, 3, 1, 2, 3], 2, 3);
This version works perfectly showing me [1,1].
So what's going wrong with the first version??? Thank you!!

The problem with the first one is that arguments applies to the .filter() callback function (the closest function scope, not the parent function scope) so arguments[i] is not what you want it to be.
You could copy those arguments into an actual array which you could then refer to from the .filter() callback.
function destroyer(arr) {
var args = [].slice.call(arguments, 1);
for ( var i = 0; i < args.length; i++ ){
arr = arr.filter(function(value){
if( value == args[i]){
return false;
}else{
return true;
}
});
}
return arr;
}
var a = destroyer([1, 2, 3, 1, 2, 3], 2, 3);
// show output
document.write(JSON.stringify(a));
Personally, I'd suggest a bit simpler version:
function destroyer(arr) {
var args = [].slice.call(arguments, 1);
return arr.filter(function(value) {
return args.indexOf(value) === -1;
});
}
var a = destroyer([1, 2, 3, 1, 2, 3], 2, 3);
// show output
document.write(JSON.stringify(a));
Which, can be written simpler in ES6 using the spread operator:
function destroyer(arr, ...args) {
return arr.filter(function(value) {
return args.indexOf(value) === -1;
});
}
var a = destroyer([1, 2, 3, 1, 2, 3], 2, 3);
// show output
document.write(JSON.stringify(a));
Or, if you prefer even shorter ES6 notation and want to use the new Array.prototype.includes():
function destroyer(arr, ...args) {
return arr.filter(value => !args.includes(value));
}
var a = destroyer([1, 2, 3, 1, 2, 3], 2, 3);
document.write(JSON.stringify(a));

I would write it like that in an es6 version:
function destroyer( arr, ...elem ) {
return arr.reduce( ( prev, next, index ) => elem.includes( arr[index] ) ? prev : prev.concat(next) , [])
}

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

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 can i write this javascript filter arguments function right?

function terminate(arr) {
var args =[];
for(i=1;i<arguments.length;i++){
}
return arr.filter(e => e!=args[0]&& e!=args[1]&&e!=args[2]);
}
terminate([3, 5, 1, 2, 2], 2, 3, 5);
//terminate([3, 5, 1, 2, 2], 2, 3, 5) should return [1]
As Jaromanda X suggested, if you're using ES2015/ES6, then this is the best solution:
function terminate(arr, ...args) {
return arr.filter(el => !args.includes(el));
}
Edit: Sorry! Array.prototype.includes isn't part of ES2015/ES6 it's part of ES2016. You'll need to use either args.indexOf(el) === -1 (like the next example) or !~args.indexOf(el) (which uses a Bitwise operator) as the filter predicate function if you're using ES2015/ES6.
For ES5 something like this would work:
function terminate(arr) {
var args = Array.prototype.slice.call(arguments, 1);
return arr.filter(function (el) {
return args.indexOf(el) === -1;
});
}

freecodecamp Challenges- Seek and Destroy

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

Is there any elegant function to find an array in array? Javascript

I want to check if an array contains an array of values rather then a value, for example
var arr = [1, 2, 3];
arr.contains([1, 2]); // returns true
// and
arr.contains([1, 5]); // must be false
There is a method called contains in underscore _.contains but it works like .indexof() in javascript instead it returns true and false and only find a value and not an array
Also there is a method Array.prototype.includes() in javascript that also take single input rather of an array
actually I want to check if second array has all the keys present in
first array I want to check with AND
for example [1,2,3,4].contains([1,4]) must return true where as [1,2,3,4].contains([1,9]) must return false, hope this makes sense,
I'm for now using underscores intersection and second array with
intersection result it must be same, its still long procedure....
You could use Array.prototype.includes() within a for loop
var arr = [1,2,3,4];
function contains(arr) {
for (var i = 0, included = true; i < arr.length
; included = included && this.includes(arr[i]), i++);
return included
}
Array.prototype.contains = contains;
console.log(arr.contains([1, 4]), arr.contains([9, 1]), arr.contains([1, 5]))
You can use a combination of every and indexOf
[1, 2].every(function(e) { return [1, 2, 3].indexOf(e) !== -1 });
would evaluate to true and
[1, 5].every(function(e) { return [1, 2, 3].indexOf(e) !== -1 });
would evaluate to false
The syntax would be a lot shorter in ES6 with arrow functions
[1, 2].every(e => [1, 2, 3].indexOf(e) !== -1)
Try this simple example
var arr = [1, 2, 3];
var searchArr = [1,2];
var isSearchArrAvailable = searchArr.filter( function(value){ if ( arr.indexOf( value ) == -1 ) { return true } else { return false; } } ).length == 0;
console.log( "is SearchArr Available " + isSearchArrAvailable );//this will print true
while var searchArr = [1,5] will print false.
You can refactor it into a function
function hasEveryElement(arr, searchArr)
{
return searchArr.filter( function(value){ if ( arr.indexOf( value ) == -1 ) { return true } else { return false; } } ).length == 0;
}
console.log( hasEveryElement([1,2,3], [1,2]) ) ;
console.log( hasEveryElement([1,2,3], [1,4]) ) ;
You can use every:
function contains(arr, arr2) {
return arr2.every(function (el) {
return arr.indexOf(el) > -1;
});
}
var arr = [1, 2, 3];
contains(arr, [1, 2]); // true
contains(arr, [1, 5]); // false
Alternatively, you could add a method to the prototype if you wanted the [].includes-style syntax, but call it something else - I've used hasAll.
if (!('hasAll' in Array.prototype)) {
Array.prototype.hasAll = function(arr) {
return arr.every(function(el) {
return this.indexOf(el) > -1;
}, this);
}
arr.hasAll([1, 2])); // true
arr.hasAll([1, 5])); // false
DEMO
Try this:
var arr = [1,2,3];
var temparr=[1,2];
var st=ArrOfArrSt(arr,temparr);
function ArrOfArrSt(arr,temparr){
var stArr= new Array();
if(temparr.length>0)
for(j in temparr){
if(arr.indexOf(temparr[j])==-1){
stArr.push('0');
}
}
return (stArr.length>0)?0:1; //whole array 0=not belong to / 1=belong to
}

Categories

Resources