removing duplicates from a nested/2D array (removing the nested duplicate element) - javascript
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;
}
Related
I want to add together the numbers of a nested array
This is what I came up with: var nestedArr = [[[1,2],[3,4]],[[5,6]]]; function sumTotal() { for(var i = 0; i < nestedArr.length; i++) { for(var j = 0; j < nestedArr[i].length; j++) { for(var k = 0; k < nestedArr[i][j].length; k++) { var arrNumSum = nestedArr[i][j][k]; arrNumSum += arrNumSum; return arrNumSum; } } } } sumTotal();
You can instead create recursive function using reduce() var nestedArr = [[[1,2],[3,4]],[[5,6]]]; function sum(arr) { return arr.reduce(function(r, e) { return r + (Array.isArray(e) ? sum(e) : e) }, 0) } console.log(sum(nestedArr))
You're overwriting arrNumSum each time through the loop. Moreover, you're returning too soon, right after the first iteration. Try this instead: var nestedArr = [[[1,2],[3,4]],[[5,6]]]; function sumTotal() { var arrNumSum = 0; for(var i = 0; i < nestedArr.length; i++) { for(var j = 0; j < nestedArr[i].length; j++) { for(var k = 0; k < nestedArr[i][j].length; k++) { arrNumSum += nestedArr[i][j][k]; } } } return arrNumSum; } console.log(sumTotal());
You could use a recusive call of Array#reduce with a named function as callback. var array = [[[1, 2], [3, 4]], [[5, 6]]], total = array.reduce(function add(r, a) { return Array.isArray(a) ? a.reduce(add, r) : r + a; }, 0); console.log(total);
for loop efficiency, make two for loops into one
So I have 2 separate 2D array, they are not necessarily the same length, and I want to make an object for each. I made this: var obj1 = {}, obj2 = {}; for (var i=0; i<arr1.length; i++) { obj1[arr1[i][1]] = arr1[i][0]; } for (var j=0; j<arr2.length; j++) { obj2[arr2[j][1]] = arr2[j][0]; } My question is if there is a way to make this with only one loop. Thanks!
You could try something like this: var obj1 = {}, obj2 = {}, length = Math.max(arr1.length, arr2.length); // get max array length for (var i = 0; i < length; i++) { // loop max array length if (i < arr1.length) { // do check for arr1 obj1[arr1[i][1]] = arr1[i][0]; } if (i < arr2.length) { // do check for arr2 obj2[arr2[i][1]] = arr2[i][0]; } } As pointed out, this may be less efficient than 2 separate loops, Although it also may be more efficient
What you really want here is a function abstraction that removes the duplication. There is nothing to make this more efficient (if you meant time complexity, not developer efficiency): function arrToObj(arr) { var obj = {}; for (var i=0; i<arr.length; i++) { obj[arr[i][1]] = arr[i][0]; } return obj; } var obj1 = arrToObj(arr1), obj2 = arrToObj(arr2); The loop is still executed twice, but it's only written once.
Something like this should work: var obj1 = {}, obj2 = {}; for (let i = 0; i < arr1.length && i < arr2.length; i++) { obj1[arr1[i][1]] = arr1[i][0]; obj2[arr2[i][1]] = arr2[i][0]; } if (arr1.length > arr2.length) { for (let i = arr2.length; i < arr1.length; i++) { obj1[arr1[i][1]] = arr1[i][0]; } } if (arr2.length > arr1.length) { for (let i = arr1.length; i < arr2.length; i++) { obj2[arr2[i][1]] = arr2[i][0]; } }
Inspired by Pete's and eur00t's answers, I suggest this one: var commonLength = Math.min(arr1.length, arr2.length); for (var i = 0; i < commonLength; i++) { obj1[arr1[i][1]] = arr1[i][0]; obj2[arr2[i][1]] = arr2[i][0]; } for (var i = commonLength; i < arr1.length; i++) { obj1[arr1[i][1]] = arr1[i][0]; } for (var i = commonLength; i < arr2.length; i++) { obj2[arr2[i][1]] = arr2[i][0]; } As the question is about efficiency, I made a jsperf test case to compare the solutions.
var obj1 = {}, for (var i=0; i<arr1.length; i++) { obj1[arr1[i][1]] = arr1[i][0]; } for (var j=0; j<arr2.length; j++, i++) { obj2[arr2[i][1]] = arr2[j][0]; } Hope this will you
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() }
Jquery to compare and return string arrays
Hi I am developing one jquery application. I am trying to compare the two arrays. For example, Firstarray=["Mike","Jack"]; SecondArray=["Mike","Jack","Andy","Cruz"]; Whenever we compare above two arrays I want to return the strings which exists in both arrays or which are common to both arrays! I tried as below. This piece of code is not working. for (var i = 0; i < Firstarray.length; i++) { for (var j = 0; j < SecondArray.length; j++) { if (Firstarray[i] == SecondArray[j]) { alert('found ' + SecondArray[j]); return; } } } Can anyone help me in this regards! Thank you very much.
You can use indexOf() function Firstarray=["Mike","Jack"]; SecondArray=["Mike","Jack","Andy","Cruz"]; var result = new Array(); for (var i = 0; i < Firstarray.length; i++) { if(SecondArray.indexOf(Firstarray[i])>=0){ result.push(Firstarray[i]); } } console.log(result);
Here is a solution using Array.prototype.filter and Array.prototype.some along with some ES6 flavor thrown in - see demo below: var firstArray=["Mike","Jack"]; var secondArray=["Mike","Jack","Andy","Cruz"]; var result = secondArray.filter(a => firstArray.some(b => a === b)); console.log(result);
check this How can I find matching values in two arrays? Array.prototype.diff = function(arr2) { var ret = []; this.sort(); arr2.sort(); for(var i = 0; i < this.length; i += 1) { if(arr2.indexOf( this[i] ) > -1){ ret.push( this[i] ); } } return ret; };
var FirstArray=["Mike","Jack"]; var SecondArray=["Mike","Jack","Andy","Cruz"]; var commonArray = Array(); var count=0; for (var i=0; i<FirstArray.length; i++) { for (var j=0;j< SecondArray.length;j++) { if (FirstArray[i] == SecondArray[j]){ commonArray[count]=FirstArray[i]; count++; } } } console.log(commonArray);
Try changing few things in your code : var Firstarray=["Mike","Jack"]; var SecondArray=["Mike","Jack","Andy","Cruz"]; var matchedData = []; for (var i = 0; i < Firstarray.length; i++) { for (var j = 0; j < SecondArray.length; j++) { if (Firstarray[i] == SecondArray[j]) { matchedData.push(SecondArray[j]); } } } alert(matchedData); working fiddle : https://jsfiddle.net/o3brcsvw/
try this var Firstarray=["Mike","Jack"]; var SecondArray=["Mike","Jack","Andy","Cruz"]; var matchedData = []; for (var i = 0; i < Firstarray.length; i++) { for (var j = 0; j < SecondArray.length; j++) { if (Firstarray[i] == SecondArray[j]) { //alert('found ' + SecondArray[j]); matchedData.push(SecondArray[j]); } } } return matchedData;
How can I use data in a string to update a javascript object?
I have the following data array: var ans = [ {"text":"x","response":false}, {"text":"y","response":false}, {"text":"z","response":true} ]; var correct = "010"; // I need to add this to the array ans Can anyone suggest how I could use use the data in the correct variable to add to the array so as to make: var ans = [ {"text":"x","response":false,"correct":false}, {"text":"y","response":false,"correct":true}, {"text":"z","response":true,"correct":false} ];
for(var i=0; i< ans.length; i++) { ans[i].correct = correct.charAt(i) == "1"; }
for (var i = 0; i < correct.length; i++) { ans[i]["correct"] = correct[i] === "1"; }
You an also do it like this(using a for-in loop). Reference: For-each over an array in JavaScript? for(key in ans){ ans[key].correct = correct.charAt(key) == "1"; }
var ans = [ {"text":"x","response":false}, {"text":"y","response":false}, {"text":"z","response":true} ]; var correct = "010"; var sep = correct.split(""); var arr = []; for (var i = 0; i < sep.length; i++) { if (sep[i] == 0) { arr.push("false"); } else { arr.push("true"); } } var len = ans.length; for (var i = 0; i < len; i++) { ans[i].correct = arr[i]; }