What's wrong with my remove function? - javascript
Array.prototype.remove = function (obj) {
for(var i = 0; i < this.length; i++) {
if(this[i] === obj) {
if (i == this.length) {
this[i] = null;
} else {
for(var j = i; j < this.length-1; j++) {
this[j] = this[j+1];
}
delete this[j]; // updated from this[j] = null; still not working.
}
}
}
return this;
};
calling it with:
write("ARRAY TEST = " + [22, 33, 44].remove(33).remove(22));
..it prints:
44,,
Why this 2 commas and how to fix my remove function to remove the commas as well?
delete on an Array will not remove the element, it will set it to undefined. And since undefined when printed results in an empty string, that explains the results of write().
You need to use splice() to remove the element. If you combine it with indexOf (you may need to define it for older browser) you get a pretty short function:
Array.prototype.remove = function (obj) {
this.splice(this.indexOf(obj), 1);
return this;
}
PS: I'm not an advocate of expanding native prototypes...
Setting the item to null leaves an item in the array (but it is a null item), which is why you see the commas still.
As previously mentioned, deleting or setting the item to null still leaves the item in the array. What you want to use is Array.splice
Here's an implementation that should work:
Array.prototype.remove = function (obj) {
for(var i = 0; i < this.length; i++) {
if(this[i] === obj)
{
this.splice(i,1);
break;
}
}
return this;
};
You don't remove the elements from the array you just set them to null.
If you need inspiration look at this remove method. It's by index and not by element.
http://ejohn.org/blog/javascript-array-remove/
try:
Array.prototype.remove = function (obj) {
for(var i = 0; i < this.length; i++) {
if(this[i] === obj) {
if (i == this.length) {
this.splice(i,1);
} else {
for(var j = i; j < this.length-1; j++) {
this[j] = this[j+1];
}
this.splice(j,1);
}
}
}
return this;
};
Array.prototype.remove = function (obj) {
for(var i = 0; i < this.length; i++) {
if(this[i] === obj) {
if (i == this.length) {
#this[i] = null;
delete this[i];
} else {
for(var j = i; j < this.length-1; j++) {
this[j] = this[j+1];
}
#this[j] = null;
delete this[i];
}
}
}
return this;
};
Pretty sure that is what you want
Related
Confused about arrays
I'm a new javascript developer from lua and I have some confusion about arrays. I'm trying to build a simple 2d array but after the initialization I keep getting an error that the array is "undefined" here's the code : var board = []; function initBoard(){ for (var i = 0; i < 8; i++){ board.push([]); for (var j = 0 ;i < 8; i++){ board[j].push([]); } } } function checkSquare(x, y){ if (typeof(board[x][y]) === ""){ return false; } else { return true; } } initBoard(); console.log(checkSquare(3, 3)); Here's the error : Cannot read property '3' of undefined`
You need not only take a look to the loops, but also to the check of the value of an item of the array. The comparison with the result of typeof with an empty string is always false, because there is no data type in Javascript Which is an empty string. For comparing the value, you could check with the value directly with a Identity/strict equality operator ===. This checks the type of the left and right side and the value as well. For objects, it check if the object has the same reference. function initBoard() { var board = []; for (var i = 0; i < 8; i++) { board.push([]); for (var j = 0; j < 8; j++) { board[i].push(''); } } return board; } function checkSquare(x, y) { if (board[x][y] === '') { // check if the item is an empty string return false; } else { return true; } } var board = initBoard(); console.log(checkSquare(3, 3));
There's a little mistale you've made while initialising. You've misplaced j with i. Try this: var board = []; function initBoard(){ for (var i = 0; i < 8; i++){ board.push([]); for (var j = 0 ;j< i; j++){ //There was a mistake here board[j].push([]); } } } function checkSquare(x, y){ if (typeof(board[x][y]) === ""){ return false; } else { return true; } } initBoard(); console.log(checkSquare(3, 3)); var board = []; function initBoard(){ for (var i = 0; i < 8; i++){ board.push([]); for (var j = 0 ;j< i; j++){ board[j].push([]); } } } function checkSquare(x, y){ if (typeof(board[x][y]) === ""){ return false; } else { return true; } } initBoard(); console.log(checkSquare(3, 3));
Two main things, you have a typo in your second loop, it should be based on j not i and when you are trying to initialize the second array you can't use push because board[j] is undefined and push is a method of an array var board = []; function initBoard(){ for (var i = 0; i < 8; i++){ board.push([]); for (var j = 0 ;j < 8; j++){ board[j] = []; } } } function checkSquare(x, y){ if (typeof(board[x][y]) === ""){ return false; } else { return true; } } initBoard(); console.log(checkSquare(3, 3));
How to get all possible combinations of elements in an array including order and lengths
function getAllCombinations(arr) { var f = function(arr) { var result = []; var temp = []; for (var i = 0; i < arr.length; i++) { temp = []; temp.push(arr[i]); result.push(temp); for (var j = 0; j < arr.length; j++) { if (j != i) { temp = []; temp.push(arr[i]); temp.push(arr[j]); result.push(temp); for (var k = 0; k < arr.length; k++) { if (k != i && k != j) { temp = []; temp.push(arr[i]); temp.push(arr[j]); temp.push(arr[k]); result.push(temp); for (var l = 0; l < arr.length; l++) { if (l != i && l != j && l != k) { temp = []; temp.push(arr[i]); temp.push(arr[j]); temp.push(arr[k]); temp.push(arr[l]); result.push(temp); } } } } } } } return result; } return f(arr); } //call this function console.log(getAllCombinations(["a", "b", "c", "d"])); [["a"],["a","b"],["a","b","c"],["a","b","c","d"],["a","b","d"],["a","b","d","c"],["a","c"],["a","c","b"],["a","c","b","d"],["a","c","d"],["a","c","d","b"],["a","d"],["a","d","b"],["a","d","b","c"],["a","d","c"],["a","d","c","b"],["b"],["b","a"],["b","a","c"],["b","a","c","d"],["b","a","d"],["b","a","d","c"],["b","c"],["b","c","a"],["b","c","a","d"],["b","c","d"],["b","c","d","a"],["b","d"],["b","d","a"],["b","d","a","c"],["b","d","c"],["b","d","c","a"],["c"],["c","a"],["c","a","b"],["c","a","b","d"],["c","a","d"],["c","a","d","b"],["c","b"],["c","b","a"],["c","b","a","d"],["c","b","d"],["c","b","d","a"],["c","d"],["c","d","a"],["c","d","a","b"],["c","d","b"],["c","d","b","a"],["d"],["d","a"],["d","a","b"],["d","a","b","c"],["d","a","c"],["d","a","c","b"],["d","b"],["d","b","a"],["d","b","a","c"],["d","b","c"],["d","b","c","a"],["d","c"],["d","c","a"],["d","c","a","b"],["d","c","b"],["d","c","b","a"]] A total of 64 combinations for a 4 length array. The function works fine but I need to make this function recursive. The for loops have to be nested based on the length of the array and the push also increased per nested loop. Really appreciate some advice.
Finally made it recursive !! Tried to work down on the the original code posted above moving each loop functionality into simple functions. function getAllCombinations(inputArray) { var resultArray = []; var combine = function() { for (var i in inputArray) { var temp = []; var tempResult = []; for (var j in arguments) { tempResult.push(inputArray[arguments[j]]); if (arguments[j] == i) { temp = false; } else if (temp) { temp.push(arguments[j]); } } if (temp) { temp.push(i); combine.apply(null, temp); } } if (tempResult.length > 0) { resultArray.push(tempResult); } return resultArray; }; return combine(); } See the older version here. Result produces 64 unique combinations for a 4 dimensional array console.log(getAllCombinations(["a", "b", "c", "d"])); [["a","b","c","d"],["a","b","c"],["a","b","d","c"],["a","b","d"],["a","b"],["a","c","b","d"],["a","c","b"],["a","c","d","b"],["a","c","d"],["a","c"],["a","d","b","c"],["a","d","b"],["a","d","c","b"],["a","d","c"],["a","d"],["a"],["b","a","c","d"],["b","a","c"],["b","a","d","c"],["b","a","d"],["b","a"],["b","c","a","d"],["b","c","a"],["b","c","d","a"],["b","c","d"],["b","c"],["b","d","a","c"],["b","d","a"],["b","d","c","a"],["b","d","c"],["b","d"],["b"],["c","a","b","d"],["c","a","b"],["c","a","d","b"],["c","a","d"],["c","a"],["c","b","a","d"],["c","b","a"],["c","b","d","a"],["c","b","d"],["c","b"],["c","d","a","b"],["c","d","a"],["c","d","b","a"],["c","d","b"],["c","d"],["c"],["d","a","b","c"],["d","a","b"],["d","a","c","b"],["d","a","c"],["d","a"],["d","b","a","c"],["d","b","a"],["d","b","c","a"],["d","b","c"],["d","b"],["d","c","a","b"],["d","c","a"],["d","c","b","a"],["d","c","b"],["d","c"],["d"]]
Here is my solution using a subroutine, and closures. Also slice is very useful here. If you found this helpful, or if you think other people will find this helpful, don't be afraid to upvote. function getMyCombinations(coll) { const result = []; (function search(currentPerm, letters) { if (letters.length === 0) return result.push(currentPerm); let trimArray = letters.slice(1); letters.forEach(letter => search(currentPerm + letter, trimArray)); })('', coll) return result; } console.log(getMyCombinations(["a", "b", "c", "d"])); I have refactored my original answer to better align with the users request. function findPerm(array, currentPerm = '', result =[]) { if (array.length === 0) return result; let trimArray = array.slice(1); array.forEach(v => { let copy = [...result]; let perm = (currentPerm + v).split(''); let res = copy.push(perm); result = findPerm(trimArray, currentPerm + v, copy); }); return result; }; console.log(findPerm(['a', 'b', 'c', 'd']));
An alternative solution, seems getting the desired output :) console.log(JSON.stringify(getMyCombinations(["a", "b", "c", "d"]))) function getMyCombinations(arry) { var len = arry.length; var tempArray = []; var result = [] var tempCount = 1; var createCombinations = function(count){ var singleLevelArray = []; arry.forEach(function(item){ if(count){//1 if(count > 1){ for(var j = 0; j < tempArray.length; j++){ if(tempArray[j].indexOf(item) === -1){ var x = tempArray[j].slice(); x.push(item); singleLevelArray.push(x); result.push(x); } } } else { for(var k = 0; k < len; k++){ if(item.indexOf(arry[k]) === -1){ tempArray.push([item, arry[k]]); result.push([item, arry[k]]); } } } } else { result.push([item]); } }) if(singleLevelArray.length){ tempArray = [] tempArray = singleLevelArray; } if(tempCount < len){ createCombinations(tempCount++); } return result; } return createCombinations() }
Uniqualize array in Javascript? [duplicate]
This question already has answers here: Remove duplicate values from JS array [duplicate] (54 answers) Closed 8 years ago. I have the following script that's supposed to uniqualize array: function uniques(arr) { var a = []; for (var i=0, l=arr.length; i<l; i++) for (var j = 0; j < arr[i].length; j++) { if (a.indexOf(arr[i][j]) === -1 && arr[i][j] !== '') { a.push(arr[i][j]); } } return a; } However, when it receives only one element, it just breaks it into the letters (which is understandable). Do you know how I make it check if it's receiving only one element and then returns it back? Thanks!
I'm not sure why you need the nested loop - you only need a single loop if you're processing a non-nested array: function uniques(arr) { if (arr.length === 1) { return arr }; var a = []; for (var i = 0, l = arr.length; i < l; i++) { if (a.indexOf(arr[i]) === -1) { a.push(arr[i]); } } return a; } DEMO If you want to process nested arrays, use a recursive function. Here I've used underscore's flatten method as the basis: function toType(x) { return ({}).toString.call(x).match(/\s([a-zA-Z]+)/)[1].toLowerCase(); } function flatten(input, output) { if (!output) { output = []; } for (var i = 0, l = input.length; i < l; i++) { var value = input[i]; if (toType(value) !== 'array' && output.indexOf(value) === -1) { output.push(value); } else { flatten(value, output); } } return output.sort(function (a, b) { return a - b; }); }; var arr = [1, 2, 3, [[4]], [10], 5, 1, 3]; flatten(arr); // [ 1, 2, 3, 4, 5, 10 ] DEMO
I think the solution is this: function uniques(arr) { if (arr.length > 1) { var a = []; for (var i=0, l=arr.length; i<l; i++) for (var j = 0; j < arr[i].length; j++) { if (a.indexOf(arr[i][j]) === -1 && arr[i][j] !== '') { a.push(arr[i][j]); } } return a; } else { return arr; } }
What you're trying to do is a linear search on the created matrix for each item in the original one. The solution below will accomplish this, but at a great cost. If your original matrix is 50x50 with unique values in each cell, it will take you 50^3 (=125000) loops to exit the function. The best technique to search, in programming science, takes O(log(N)) that means that if you'll use it on your problem it will take log(50^2) (=11) loops. function uniques(arr) { var items = []; var a = arr.map(function(row, i) { return row.map(function(cell, j) { if (items.indexOf(cell) >= 0) { items.push(cell); return cell; } }); }); }
removing duplicates from a nested/2D array (removing the nested duplicate element)
So that: array = [[12,13,24],[24,22,11],[11,44,55]] would return: cleanedArray = [[12,13,24],[22,11],[44,55]] I'm surprised not to have found this answered here.
var array = [[12,13,24],[24,22,11],[11,44,55]]; var output = []; var found = {}; for (var i = 0; i < array.length; i++) { output.push([]); for (var j = 0; j < array[i].length; j++) { if (!found[array[i][j]]) { found[array[i][j]] = true; output[i].push(array[i][j]); } } } console.log(output);
Are you looking for a function that does this for just two-dimensional arrays? If so, then I think this would work: Array.prototype.clean = function() { var found = []; for(var i = 0; i < this.length; i++) { for(var j = 0; j < this[i].length; j++) { if(found.indexOf(this[i][j]) != -1) { this[i].splice(j, 1); } else { found.push(this[i][j]); } } } return this; }; If it's just a one-dimensional array you're looking for, then: Array.prototype.clean = function() { var found = []; for(var i = 0; i < this.length; i++) { if(found.indexOf(this[i]) != -1) { this.splice(i, 1); } else { found.push(this[i]); } } return this; }; this would work. If you're doing either of those, then do .clean() on your array to clean it up.
A simple function that modifies the original array is: function removeDups(a) { var item, j, found = {}; for (var i=0, iLen=a.length; i<iLen; i++) { item = a[i]; j=item.length; while (j--) { found.hasOwnProperty(item[j])? item.splice(j,1) : found[item[j]] = ''; } } return a; }
Javascript: Filtering twodimensional array
There's plenty examples available on how to sort an javascript array based on it's numeric values. What would however be appropriate way to fetch all elements from myArray with the property prop1 with it's according value value1? Here's my array: var myArray = [ { "id":"2", "name":"My name", "properties":{"prop1":"value1"} }]; Thanks
You can just access it by dot or bracket notation and push the matching members to your new/filtered array, for example: var newArray = []; for(var i=0, l = myArray.length; i<l; i++) { if(myArray[i].properties.prop1 == "value1") newArray.push(myArray[i]); } Your question is a bit ambiguous though, if you're trying to get the {"prop1":"value1"} object, not the parent, then just change newArray.push(myArray[i]) to newArray.push(myArray[i].properties).
Provide a compare function to sort by arbitrary properties: function compareMyObjects(a, b) { var valA = a.properties.prop1.value1; var valB = b.properties.prop1.value1; if(valA > valB) return 1; if(valA < valB) return -1; return 0; } myArray.sort(compareMyObjects); https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/sort
Go through each element in your array. For each element, check each property to see if it matches the one you're looking for. function filterArray(array, property, value) { var newArray = []; for (var i = 0; i < array.length; i++) { for (var j in array[i].properties) { if (j === property && array[i].properties.hasOwnProperty(j)) { if (array[i].properties[j] == value) { newArray.push(array[i]); } } } } }
var newarray=myarray.filter(function(itm){ return itm.properties.prop1==='value1'; }); Filter, like the array methods indexOf and map, may be worth providing for browsers that don't have it- this version is from Mozilla Developer Site- if(!Array.prototype.filter){ Array.prototype.filter= function(fun, scope){ var L= this.length, A= [], i= 0, val; if(typeof fun== 'function'){ while(i< L){ if(i in this){ val= this[i]; if(fun.call(scope, val, i, this)){ A[A.length]= val; } } ++i; } } return A; } }