OBJECTIVE
I am trying to highlight the dfferences between two arrays. Please note that arr1 and arr2 will vary in length and have multiple types present (strings and numbers).
MY CODE
function diff(arr1, arr2) {
var diffArr = [];
if (arr1.length >= arr2.length) {
for (var i = 0; i < arr1.length; i++){
if (arr2.indexOf(arr1[i]) < 0) {
diffArr.push(arr1[i]);
}
}
} else {
for (var j = 0; j < arr2.length; j++){
if (arr1.indexOf(arr2[j]) < 0) {
diffArr.push(arr2[j]);
}
}
}
return diffArr;
}
ISSUES
diff([1, 2, 'cat', 'fish'], [1, 2, 3,'dog']); //returns only ['cat', 'fish']
I am pretty sure that my code is only returning the duplicates in one of the arrays via diffArr.push (even if there are unique values in both arrays). However, I am unsure how to overcome this.
My references
Removes Duplicates from Javascript Arrays
Removed Duplicates from an Array Quickly
Javascript Array Difference
Your code currently only crawls through one array (let's call it A) and pushes in all the A values that don't exist in B. You never go the other way and push in the B values that don't exist in A. There's also no need to have different behavior based on which array is longer. Here is the final answer in a simple way:
function diff(arr1, arr2) {
var diffArr = [];
for (var i = 0; i < arr1.length; i++) {
if (arr2.indexOf(arr1[i]) < 0) diffArr.push(arr1[i]);
}
for (var j = 0; j < arr2.length; j++) {
if (arr1.indexOf(arr2[j]) < 0) diffArr.push(arr2[j]);
}
return diffArr;
}
And in a slightly more functional way:
function diff(arr1, arr2) {
var elsIn1Not2 = arr1.filter(function(el){ return arr2.indexOf(el) < 0; });
var elsIn2Not1 = arr2.filter(function(el){ return arr1.indexOf(el) < 0; });
return elsIn1Not2.concat(elsIn2Not1);
}
Both functions return [ 'cat', 'fish', 3, 'dog' ] for your example.
function diff(arr1, arr2) {
var diffArr = {};
if (arr1.length >= arr2.length) {
for (var i = 0; i < arr1.length; i++){
if (arr2.indexOf(arr1[i]) < 0) {
diffArr[arr1[i]] = 1;
}
}
} else {
for (var j = 0; j < arr2.length; j++){
if (arr1.indexOf(arr2[j]) < 0) {
diffArr[arr2[j]] = 2;
}
}
}
return diffArr.keys();
}
Related
Please help me to solve this leetcode problem using javascript as I am a beginner and dont know why this code is not working
Ques: Given an array of integers where 1 ≤ a[i] ≤ n (n = size of array), some elements appear twice and others appear once.
Find all the elements of [1, n] inclusive that do not appear in this array.
var findDisappearedNumbers = function (nums) {
var numLength = nums.length;
nums.sort(function (a, b) { return a - b });
for (var i = 0; i < nums.length - 1; i++) {
if (nums[i + 1] === nums[i]) {
nums.splice(i, 1);
}
}
for (var k = 0; k < nums.length; k++) {
for (var j = 1; j <= numLength; j++) {
if (nums[k] !== j) {
return j;
}
}
}
};
if there is any error in my code please let me know;
i have done the following thing
first i have sorted the array in ascending order
then i have cut all the duplicate elements
then i have created loop that will check if nums[k] !== j ;
and it will return j which is the missing number;
for example this is the testcase [4,3,2,7,8,2,3,1]
first my code will sort this in ascending order [1,2,2,3,3,4,7,8]
then it will remove all duplicate elements and it will return [1,2,3,4,,7,8]
and then it will check nums[k] is not equal to j and it will print j
I think it'd be easier to create a Set of numbers from 1 to n, then just iterate through the array and delete every found item from the set:
var findDisappearedNumbers = function(nums) {
const set = new Set();
for (let i = 0; i < nums.length; i++) {
set.add(i + 1);
}
for (const num of nums) {
set.delete(num);
}
return [...set];
};
console.log(findDisappearedNumbers([4,3,2,7,8,2,3,1]));
To fix your existing code, I'm not sure what the logic you're trying to implement in the lower section, but you can iterate from 1 to numLength (in the outer loop, not the inner loop) and check to see if the given number is anywhere in the array. Also, since you're mutating the array with splice while iterating over it in the upper loop, make sure to subtract one from i at the same time so you don't skip an element.
var findDisappearedNumbers = function(nums) {
var numLength = nums.length;
nums.sort(function(a, b) {
return a - b
});
for (var i = 0; i < nums.length - 1; i++) {
if (nums[i + 1] === nums[i]) {
nums.splice(i, 1);
i--;
}
}
const notFound = [];
outer:
for (var j = 1; j < numLength; j++) {
for (var k = 0; k < nums.length; k++) {
if (nums[k] === j) {
continue outer;
}
}
notFound.push(j);
}
return notFound;
};
console.log(findDisappearedNumbers([4, 3, 2, 7, 8, 2, 3, 1]));
#CertainPerformance certainly cracked it again using the modern Set class. Here is a slighly more conservative approach using an old fashioned object:
console.log(missingIn([4,3,2,7,8,2,3,1]));
function missingIn(arr){
const o={};
arr.forEach((n,i)=>o[i+1]=1 );
arr.forEach((n) =>delete o[n] );
return Object.keys(o).map(v=>+v);
}
My solution for the problem to find the missing element
var findDisappearedNumbers = function(nums) {
const map={};
const result=[];
for(let a=0;a<nums.length;a++){
map[nums[a]]=a;
}
for(let b=0;b<nums.length;b++){
if(map[b+1]===undefined){
result.push(b+1)
}
}
return result;
};
Example 1:
Input: nums = [4,3,2,7,8,2,3,1]
Output: [5,6]
Example 2:
Input: nums = [1,1]
Output: [2]
Trying to count possible combinations to get a targetTotal. Using powerSet returns the sum without adding itself. E.g [1,2,3,5] returns [3+1] for a targetSum of 4, whereas I expect to get [1+1+1+1], [2+2], [3+1].
Do you have any ideas how I could make it count itself first as a case?
function powerset(arr) {
var ps = [[]];
for (var i=0; i < arr.length; i++) {
for (var j = 0, len = ps.length; j < len; j++) {
ps.push(ps[j].concat(arr[i]));
}
}
return ps;
}
function sum(arr) {
var total = 0;
for (var i = 0; i < arr.length; i++)
total += arr[i];
return total
}
function findSums(numbers, targetSum) {
var sumSets = [];
var numberSets = powerset(numbers);
for (var i=0; i < numberSets.length; i++) {
var numberSet = numberSets[i];
if (sum(numberSet) == targetSum)
sumSets.push(numberSet);
}
return sumSets;
}
Example invocation:
findSums([1,2,3,4,5],6); [[2,3], [1,4], [5], [1,1,1,1,1,1], [2,2,2], [3,3]]
I come from a Ruby background, which features an enumerable class. In Ruby, I can easily find combinations of array elements.
array.combination(2).count
I know that JavaScript doesn't feature such built in functions, so I was wondering how I could implement this in JS. I was thinking something like
I have an array as follows
var numbers = [9,7,12]
var combos = []
for (var i = 0; i < numbers.length; i++) {
combos.push([numbers[i], numbers[i+1])
}
By the way, the possible combos are
[9,7], [9,12] and [7,12]
so by calling the length function on this array, 3 would be returned.
Any ideas?
How about:
for (var i = 0; i < numbers.length; i++)
for (var j = i + 1; j < numbers.length; j++)
combos.push([numbers[i], numbers[j]]);
Are you strictly talking about 2-combinations of the array or are you interested in a k-combinations solution?
Found this in this gist
function k_combinations(set, k) {
var i, j, combs, head, tailcombs;
if (k > set.length || k <= 0) {
return [];
}
if (k == set.length) {
return [set];
}
if (k == 1) {
combs = [];
for (i = 0; i < set.length; i++) {
combs.push([set[i]]);
}
return combs;
}
// Assert {1 < k < set.length}
combs = [];
for (i = 0; i < set.length - k + 1; i++) {
head = set.slice(i, i+1);
tailcombs = k_combinations(set.slice(i + 1), k - 1);
for (j = 0; j < tailcombs.length; j++) {
combs.push(head.concat(tailcombs[j]));
}
}
return combs;
}
Here's a recursive function, which should work for any number:
function combination(arr, num) {
var r= [];
for(var i = 0 ; i < arr.length ; i++) {
if(num===1) r.push([arr[i]]);
else {
combination(arr.slice(i+1), num-1).forEach(function(val) {
r.push([].concat(arr[i], val));
});
}
}
return r;
} //combination
Working Fiddle
i am trying to make a for loop out of a var variable but it doesn't work. For some reason tempArray.length is always undefined, it never return anything different. Can anyone help ?
for (i = 0; i < arr.length; i++) {
tempArray = arr[i];
for (k = 0; k <= tempArray.length; i++) {
if (tempArray[k] != /[0-9]+/) {
countinue;
}
var tempArray = [];
for (i = 0; i < arr.length; i++) {
tempArray = arr[i];
}
for (k = 0; k <= tempArray.length; i++) {
if (tempArray[k] != /[0-9]+/) {
countinue;
}
}
Temp array needs to be set to an array.
Loop through and build tempArray first, then loop through the temp array and do what ever you need to.
The following code will generate 10 arrays, each with 10 subarrays, each with 10 subarrays, each with 10 subarrays.
paths = [];
for (var i = 0, len_i = 10; i < len_i; ++i) { // 1st dimension
paths.push([]);
for (var j = 0, len_j = 10; j < len_j; ++j) { // 2nd dimension
paths[i].push([]);
for (var k = 0, len_k = 10; k < len_k; ++k) { // 3rd dimension
paths[i][j].push([]);
for (var l = 0, len_l = 10; l < len_l; ++l) { // 4th dimension
paths[i][j][k].push([]);
paths[i][j][k][l] = [];
}
}
}
}
I will eventually need to do this with more dimensions and am curious to know if any ingenious developers out there can accomplish this with a function of the form:
function makePaths(quantityInEachArray, dimensions) {
paths = [];
quantityInEachArray = (typeof quantityInEachArray === "undefined") ? 10 : quantityInEachArray;
dimensions = (typeof dimensions === "undefined") ? 4 : dimensions;
// Do some magic
return paths;
}
That function, in its default form, would return the same thing as the for loops I demonstrated above.
I understand that this is not a standard practice but I am doing it for a very specific reason and need to test the performance of it.
How do I modify this code to produce nth dimensional arrays?
You can use recursive function:
function nthArray(n, l) {
if(n < 1) return;
var arr = new Array(l);
for(var i=0; i<l; ++i)
arr[i] = nthArray(n-1, l);
return arr;
}
A simple magic would be (without recursion):
paths = []
arrays = [paths]
for (var i = 0; i < dimensions; i++) {
tmpArr = []
for (var k = 0; k < arrays.length; k++) {
for (var j = 0; j < size; j++) {
val = []
tmpArr.push(val)
arrays[k].push(val)
}
}
arrays = tmpArr
}
(I am not very fluent in javascript, you probably need to declare vars at the beginning and every thing, but that's the idea)