I am answering this exercise in FreeCodeCamp here's the instruction
Drop it
Given the array arr, iterate through and remove each element starting from the first element (the 0 index) until the function func returns true when the iterated element is passed through it.
Then return the rest of the array once the condition is satisfied, otherwise, arr should be returned as an empty array.
this is what I have so far. I used the map function to iterate the indexes of array then check if it met the condition of the function parameter inside the map. In this case, the function should return only the numbers less than 3 but I can't get rid of 3 when returning it.
function dropElements(arr, func) {
return arr.map(x => func(x) ? x : "");
}
console.log(dropElements([1, 2, 3], function(n) {return n < 3; }));
You could take a closure over a boolean value and keep a true value for the rest of the array for filtering.
Source of data/results: https://www.freecodecamp.org/learn/javascript-algorithms-and-data-structures/intermediate-algorithm-scripting/drop-it
function dropElements(arr, func) {
return arr.filter((b => v => b ||= func(v))(false));
}
console.log(...dropElements([1, 2, 3], function(n) { return n < 3; })); // [1, 2, 3]
console.log(...dropElements([1, 2, 3, 4], function(n) { return n >= 3; })); // [3, 4]
console.log(...dropElements([0, 1, 0, 1], function(n) { return n === 1; })); // [1, 0, 1]
console.log(...dropElements([1, 2, 3], function(n) { return n > 0; })); // [1, 2, 3]
console.log(...dropElements([1, 2, 3, 4], function(n) { return n > 5; })); // []
console.log(...dropElements([1, 2, 3, 7, 4], function(n) { return n > 3; })); // [7, 4]
console.log(...dropElements([1, 2, 3, 9, 2], function(n) { return n > 2; })); // [3, 9, 2]
Would suggest using a filter, which returns another array:
function dropElements(arr) {
return arr.filter(x => x < 3);
}
const someArray = [1, 2, 3];
console.log(dropElements(someArray)); // [1, 2]
It says "remove elements" so I'm gonna mutate the array that was passed in.
function dropElements(arr, func) {
while (arr.length && !func(arr[0])) {
arr.splice(0, 1);
}
return arr;
}
console.log(dropElements([1, 2, 3], function(n) {return n < 3; }));
Related
I'm trying to obtain // [2,6,0,8,4] from the function:
let getValidPassword = arr => {
let x = [];
for (let i in arr) {
for (let j in arr[i]) {
if (arr[i][j] % 2 !== 0) {
break;
} else {
x += arr[i][j];
}
}
}
return x
};
var loggedPasscodes = [
[1, 4, 4, 1],
[1, 2, 3, 1],
[2, 6, 0, 8],
[5, 5, 5, 5],
[4, 3, 4, 3]
];
console.log(getValidPassword(loggedPasscodes));
However when I run the typeof x, I'm getting a string(I though it was a number) and when I print x I get 26084 instead of [26084]
what witchcraft is this?
I though setting x to [ ] would make the trick...
thank you.
The problem here is that you have declared x=[] but you are modifying it as x += arr[i][j]; as soon as javascript gets to this line. It treats the array as string calling x.toString() internally and appending to that string. For example if you declare an array as a=[] and call a+=1 then a will become "1". In javascript everything is value typed, it doesn't matter what you declare when you assign some value to it or do some operation on the variable, it gets converted to the type of value.
I would recommend you to go through this
let getValidPassword = arr => {
let x = [];
let temp = [];
for (let i in arr) {
for (let j in arr[i]) {
if (arr[i][j] % 2 !== 0) {
break;
} else {
temp.push(arr[i][j]);
}
if(temp.length == arr[i].length)
x = temp.slice();
}
}
return x
};
var loggedPasscodes = [
[1, 4, 4, 1],
[1, 2, 3, 1],
[2, 6, 0, 8],
[5, 5, 5, 5],
[4, 3, 4, 3]
];
console.log(getValidPassword(loggedPasscodes));
The problem is that you are incrementing your variable, to add an element to an array you need to use the push() method.
Correct code:
let getValidPassword = arr => {
let x = [];
for (let i in arr) {
for (let j in arr[i]) {
if (arr[i][j] % 2 !== 0) {
break;
} else {
x.push(arr[i][j]);
}
}
}
return x
};
var loggedPasscodes = [
[1, 4, 4, 1],
[1, 2, 3, 1],
[2, 6, 0, 8],
[5, 5, 5, 5],
[4, 3, 4, 3]
];
console.log(getValidPassword(loggedPasscodes));
When you concatenate an array (which is what += is doing) it first converts the array and the value being appended to strings.
In order to add elements to the x array use x.push(arr[i][j]), this will insert them without type conversion.
function destroyer(arr) {
var arry=[];
for(var i=1;i<arr.length;i++)
{
arr[0] = arr[0].filter(cc => cc != arr[i]);
}
return arry;
}
destroyer([1, 2, 3, 1, 2, 3], 2, 3);
I basically have to return all the elements of the first sub-array which arent present in the rest of array.
Its displaying "arr[0].filter isnt a function.
destroyer([1, 2, 3, 1, 2, 3], 2, 3) should return [1, 1].
I basically have to return all the elements of the first sub-array which arent present in the array.
You aren't doing anything with the other arguments provided to the destroyer function - you have to test those arguments against arr, you shouldn't be testing arr against itself.
function destroyer() {
const [arr, ...excludeArr] = arguments;
return arr.filter(elm => !excludeArr.includes(elm));
}
console.log(
destroyer([1, 2, 3, 1, 2, 3], 2, 3)
);
function destroyer(arr, x, y) {
return arr.filter(item => (item != x) && (item != y))
}
console.log(destroyer([1, 2, 3, 1, 2, 3], 2, 3))
const destroyer = (arr, ...args) => {
return arr.filter(item => args.indexOf(item) < 0);
};
const result = destroyer([1, 2, 3, 1, 2, 3], 2, 3);
console.log(result);
as you said you should filter first subarray but you are sending only 1 array with int values and other values as argument, the actual usage of this function should be
function destroyer(arr) {
for(var i = 1; i < arr.length; i++)
{
arr[0] = arr[0].filter(cc => cc != arr[i]);
}
return arr[0];
}
destroyer([[1, 2, 3, 1, 2, 3], 2, 3]);
You forgot to call your method using the array. you have to surround it with another pair of [].
You can simply return the filtered arr[0] to get what you want.
function destroyer(arr) {
for (var i = 1; i < arr.length; i++) {
arr[0] = arr[0].filter(cc => cc != arr[i]);
}
return arr[0];
}
console.log(destroyer([[1, 2, 3, 1, 2, 3], 2, 3]));
function theHighest(data) {
let twoLargest = data.map((x) => {
return x.reduce((prev, curr) => {
return curr
})
})
return twoLargest //returns [3,5,8]
}
console.log(theHighest([[1, 2, 3], [3, 4, 5], [6, 7, 8]]))
The above function can return the largest numbers in each array and if it could return prev along with curr in the same array the job would be done and the desired result would be achieved which is [2,3,4,5,7,8]
How can I return this without using for loops at all?
If I use for loops here is how I do it:
function theHighest(data) {
let highestValues = []
for (let i = 0; i < data.length; i++) {
let first = 0
let second = 0
for (let j = 0; j < data[i].length; j++) {
if (first < data[i][j]) {
second = first;
first = data[i][j];
}
else if (second < data[i][j]) {
second = data[i][j];
}
}
highestValues.push(first, second)
}
return highestValues
}
console.log(theHighest([[1, 2, 3], [3, 4, 5], [6, 7, 8]]))
Thank you!
You could take a copy, sort the array and return the two max values.
function theHighest(data) {
return [].concat(...data.map(a => a.slice().sort((a, b) => a - b).slice(-2)));
}
console.log(theHighest([[1, 2, 3], [3, 4, 5], [6, 7, 8]]));
You need to sort the array as well if it not sorted
function theHighest(data) {
let twoLargest = data.map((x) => {
// Get two largest integers
return x.sort().slice(-2);
})
// Flatten the array
return Array.prototype.concat(...twoLargest);
}
console.log(theHighest([[1, 2, 3], [3, 4, 5], [6, 7, 8]]))
You can also use reduce and sort
var output = arr.reduce( (a, c) => a.concat(c.sort().slice(-2)), [] );
outputs [2,3,4,5,7,8]
Demo
var arr = [[1, 2, 3], [3, 4, 5], [6, 7, 8]];
var output = arr.reduce( (a, c) => a.concat(c.sort().slice(-2)), [] );
console.log( output );
Given an array and subsequent unknown number of arguments, how can I remove all elements from the initial array that are of the same value as these arguments? This is what I have so far:
function destroyer(arr) {
var arrayOfArgs = [];
var newArray = [];
for (var i = 0; i < arguments.length; i++) {
newArray = arr.filter(function (value) {
return value !== arguments[i + 1];
});
}
return newArray;
}
destroyer([1, 2, 3, 1, 2, 3], 2, 3);
You can use Array#filter with arrow function Array#includes and rest parameters.
Demo
function destroyer(arr, ...remove) {
return arr.filter(e => !remove.includes(e));
}
console.log(destroyer([1, 2, 3, 1, 2, 3], 2, 3));
function destroyer(arr, ...remove) {
return arr.filter(e => !remove.includes(e));
}
var updatedArr = destroyer([1, 2, 3, 1, 2, 3], 2, 3);
console.log(updatedArr);
Equivalent Code in ES5:
function destroyer(arr) {
var toRemove = [].slice.call(arguments, 1);
return arr.filter(function(e) {
return toRemove.indexOf(e) === -1;
});
}
console.log(destroyer([1, 2, 3, 1, 2, 3], 2, 3));
function destroyer(arr) {
var toRemove = [].slice.call(arguments, 1);
return arr.filter(function (e) {
return toRemove.indexOf(e) === -1;
});
}
console.log(destroyer([1, 2, 3, 1, 2, 3], 2, 3));
Use rest parameters to specify the subsequent arguments, Array.prototype.filter() with an arrow function to filter the arr, and Array.prototype.includes() to determine whether args contains specific item.
function destroyer(arr, ...args) {
return arr.filter(x=> !args.includes(x))
}
console.log(destroyer([1, 2, 3, 1, 2, 3], 2, 3))
So I have this code now, and in input I have in ascending order my name's letters "ahimrsu". I need to show up the right number for "mariush" from all combinations which should to be 2170. For now it only show ahimrsu, ahimrus, ahimsru, ahimsur, ahimurs, ahimusr, ahirmus, ahirmsu.... etc How can I do this?
<!DOCTYPE HTML>
<html>
<head>
<!--Script Function Start Here-->
<script type="text/javascript">
function perms(data) {
if (!(data instanceof Array)) {
throw new TypeError("input data must be an Array");
}
data = data.slice(); // make a copy
var permutations = [],
stack = [];
function doPerm() {
if (data.length == 0) {
permutations.push(stack.slice());
}
for (var i = 0; i < data.length; i++) {
var x = data.splice(i, 1);
stack.push(x);
doPerm();
stack.pop();
data.splice(i, 0, x);
}
}
doPerm();
return permutations;
}
var input = "ahimrsu".split('');
var result = perms(input);
for (var i = 0; i < result.length; i++) {
result[i] = result[i].join('');
}
console.log(result);
</script>
<!--Header start here-->
</head>
<body>
<!--Script Result-->
<script type="text/javascript">
document.write(result);
</script>
</body>
</html>
This is my solution from the following answer: https://stackoverflow.com/a/18879232/783743
var permute = (function () {
return permute;
function permute(list) {
return list.length ?
list.reduce(permutate, []) :
[[]];
}
function permutate(permutations, item, index, list) {
return permutations.concat(permute(
list.slice(0, index).concat(
list.slice(index + 1)))
.map(concat, [item]));
}
function concat(list) {
return this.concat(list);
}
}());
You can use the permute function to find all the permutations of an array:
var array = "ahimrsu".split("");
var permutations = permute(array).map(join);
var index = permutations.indexOf("maruish");
function join(array) {
return array.join("");
}
The algorithm is very simple to understand:
We want a function permute of the type [a] -> [[a]] (i.e. given a list of as it returns a list of permutations of the input).
Given the empty list ([]) an an input, the output is an empty list of permutations ([[]]).
Otherwise for every element:
We remove the element from the list.
We recursively find the permutations of the remaining elements.
We add the element we removed to the beginning of every permutation.
For example, suppose we want to find the permutation of the array [1, 2, 3]:
1. permute([1, 2, 3]) === [1, 2, 3].reduce(permutate, [])
1. permutate([], 1, 0, [1, 2, 3])
1. permute([2, 3]) === [2, 3].reduce(permutate, [])
1. permutate([], 2, 0, [2, 3])
1. permute([3]) === [3].reduce(permutate, [])
1. permutate([], 3, 0, [3])
1. permute([]) === [[]]
2. [[]].map(concat, [3]) === [[3]]
3. [].concat([[3]]) === [[3]]
2. [[3]].map(concat, [2]) === [[2, 3]]
3. [].concat([[2, 3]]) === [[2, 3]]
2. permutate([[2, 3]], 3, 1, [2, 3])
1. permute([2]) === [2].reduce(permutate, [])
1. permutate([], 2, 0, [2])
1. permute([]) === [[]]
2. [[]].map(concat, [2]) === [[2]]
3. [].concat([[2]]) === [[2]]
2. [[2]].map(concat, [3]) === [[3, 2]]
3. [[2, 3]].concat([[3, 2]]) === [[2, 3], [3, 2]]
2. [[2, 3], [3, 2]].map(concat, [1]) === [[1, 2, 3], [1, 3, 2]]
3. [].concat([[1, 2, 3], [1, 3, 2]]) === [[1, 2, 3], [1, 3, 2]]
2. permutate([[1, 2, 3], [1, 3, 2]], 2, 1, [1, 2, 3])
1. permute([1, 3]) === [1, 3].reduce(permutate, [])
2. [[1, 3], [3, 1]].map(concat, [2]) === [[2, 1, 3], [2, 3, 1]]
3. [[1, 2, 3], [1, 3, 2]].concat([[2, 1, 3], [2, 3, 1]])
3. permutate([[1, 2, 3], [1, 3, 2], [2, 1, 3], [2, 3, 1]], 3, 2, [1, 2, 3])
1. permute([1, 2]) === [1, 2].reduce(permutate, [])
2. [[1, 2], [2, 1]].map(concat, [3]) === [[3, 1, 2], [3, 2, 1]]
3. [[1, 2, 3], [1, 3, 2], [2, 1, 3], [2, 3, 1]].concat([[3, 1, 2], [3, 2, 1]])
Old explanation:
First we remove the first element of the list. Hence we have item 1 and list [2, 3].
Next we find the permutations of [2, 3].
We remove the first element. Hence we have item 2 and list [3].
Next we find the permutations of [3].
We remove the first element. Hence we have item 3 and list [].
Next we find the permutations of [] which is [[]].
We add 3 to the beginning of each permutation.
The result is [[3]].
We add 2 to the beginning of each permutation.
The result is [[2, 3]].
We remove the second element. Hence we have item 3 and list [[2]].
Next we find the permutations of [2].
We remove the first element. Hence we have item 2 and list [].
Next we find the permutations of [] which is [[]].
We add 2 to the beginning of each permutation.
The result is [[2]].
We add 3 to the beginning of each permutation.
The result is [[3, 2]].
We combine the two two lists.
The result is [[2, 3], [3, 2]].
We add 1 to the beginning of each permutation.
The result is [[1, 2, 3], [1, 3, 2]].
Same for the second element: item 2 and list [1, 3].
Same for the third element: item 3 and list [1, 2].
We combine the three lists.
The result is [[1, 2, 3], [1, 3, 2], [2, 1, 3], [2, 3, 1], [3, 1, 2], [3, 2, 1]].
See the demo:
var permute = (function () {
return permute;
function permute(list) {
return list.length ?
list.reduce(permutate, []) :
[[]];
}
function permutate(permutations, item, index, list) {
return permutations.concat(permute(
list.slice(0, index).concat(
list.slice(index + 1)))
.map(concat, [item]));
}
function concat(list) {
return this.concat(list);
}
}());
var array = "ahimrsu".split("");
var permutations = permute(array).map(join);
var index = permutations.indexOf("maruish");
alert("maruish is the " + (index + 1) + "th permutation of ahimrsu.");
function join(array) {
return array.join("");
}
Hope that helps.
Algorithm for string permutation will be a little bit more complicated with recursive step (it's possible to code it without recursion though).
The next javascript implementation is based on the description of the algorithm from this answer:
Remove the first letter
Find all the permutations of the remaining letters (recursive step)
Reinsert the letter that was removed in every possible location.
Implementation then something like this:
function permutation(str) {
if (str.length == 1) {
return [str];
}
var first = str[0], // Step #1
perms = permutation(str.slice(1)), // Step #2
result = [];
// Step #3
for (var i = 0; i < perms.length; i++) {
for (var j = 0; j <= perms[i].length; j++) {
result.push( perms[i].slice(0, j) + first + perms[i].slice(j) );
}
}
return result;
}
console.log(permutation('ahimrsu'));
Above implementation gives 5040 combinations, which seems to be correct, since 7! == 5040 (number of permutations is a factorial of the number of chars).
Now when you have all possible permutations array you can easily find specific string occurrence:
var combinations = permutation('ahimrsu');
var index = combinations.indexOf('mariush'); // Index of the "mariush"
alert('"mariush" is the ' + (index + 1) + 'th permutation of "ahimrsu".');
Well, 'mariush' is actually permutation 2220 if we are
using your ordering scheme:
/*jslint white: true*/
var perm = function(s){
'use strict';
if(s.length === 1){
return [s];
}
// For each character c in s, generate the permuations p of all
// the other letters in s, prefixed with c.
return [].reduce.call(s, function(p,c,i){ // permutations, char, index
var other = s.slice(0,i) + s.slice(i+1);
return p.concat(perm(other).map(function(oneperm){
return c + oneperm;
}));
}, []);
};
alert(perm('ahimrsu').indexOf('mariush') + 1); // 2220