JavaScript Elements of array being equal function not working - javascript

While taking some online JS tests, I am stuck on why my function for testing if the elements within two arrays are equal is not working. I am using the function to make sure that the new array does not have duplicate values.
The following is my function for testing if the elements of the arrays are equal or not:
const isEqualArr = (a, b) => {
for (let i = 0; i < a.length; i++) {
if (a[i] != b[i]) {
return false;
}
}
return true;
};
I call to the function within a for loop, then I test for undefined, because the first time around, the outputArr is empty
for (let x = 0; x < numsLength; x++) {
if (typeof outputArr[x] != 'undefined') {
if (isEqualArr(tempArr, [outputArr[x]])) {
However, the result shows that there are duplicates:
0: Array [ -1, 0, 1 ]
​
1: Array [ -1, 2, -1 ]
​
2: Array []
​
3: Array [ -1, -1, 2 ]
​
4: Array []
​
5: Array [ 0, 1, -1 ]
​
6: Array [ 0, -1, 1 ]
​
7: Array [ 1, 0, -1 ]
​
8: Array [ -1, 0, 1 ]
The other issue is that not only do I have two null arrays (duplicates), but when I test for null before the push, it is not working either:
if(tempArr != null ) {
outputArr.push(tempArr);
}
I have tried tempArr[0] != null, tempArr[0] != '' as well as
if (typeof tempArr[0] != 'undefined')
But it still inserts null arrays into the outputArr.
The following is the premise of the test:
Given an integer array nums, return all the triplets [nums[i], nums[j], nums[k]] such that i != j, i != k, and j != k, and nums[i] + nums[j] + nums[k] == 0.
Notice that the solution set must not contain duplicate triplets. Given nums = [-1,0,1,2,-1,-4]
The following code is my solution, but the duplicate entries, as well as the null entries, makes this an incorrect solution. If you guys can see why my isEqualArr function is at fault, then I would appreciate it.
const threeSum = (nums) => {
let numsLength = nums.length;
let tempArr = [];
let outputArr = [];
if (numsLength > 3) {
for (let i = 0; i < numsLength; i++) {
for (let j = 1; j < numsLength; j++) {
for (let k = 2; k < numsLength; k++) {
if (
i != j &&
i != k &&
j != k &&
nums[i] + nums[j] + nums[k] == 0
) {
tempArr[0] = nums[i];
tempArr[1] = nums[j];
tempArr[2] = nums[k];
for (let x = 0; x < numsLength; x++) {
if (typeof outputArr[x] != 'undefined') {
if (!isEqualArr(tempArr, [outputArr[x]])) {
if (typeof tempArr[0] != 'undefined') {
outputArr.push(tempArr);
console.log(
'temp: ' + tempArr + ' outputArr: ' + outputArr[x]
);
console.log(
'compare: ' + isEqualArr(tempArr, outputArr[x])
);
console.log(outputArr);
tempArr = [];
}
}
}
}
if (i == 0) {
outputArr.push(tempArr);
tempArr = [];
} else {
// do nothing
}
}
}
}
}
}
return outputArr;
};
const isEqualArr = (a, b) => {
for (let i = 0; i < a.length; i++) {
if (a[i] != b[i]) {
return false;
}
}
return true;
};
EDIT: I was able to eliminate the null entries by moving the code that checks if it is the first time to run above the for loop:
if (i == 0) {
outputArr.push(tempArr);
tempArr = [];
} else {
// do nothing
}
for (let x = 0; x < numsLength; x++) {
if (typeof outputArr[x] != 'undefined') {
if (!isEqualArr(tempArr, [outputArr[x]])) {
if (typeof tempArr[0] != 'undefined') {
outputArr.push(tempArr);
console.log(
'temp: ' + tempArr + ' outputArr: ' + outputArr[x]
);
console.log(
'compare: ' + isEqualArr(tempArr, outputArr[x])
);
console.log(outputArr);
tempArr = [];
}
}
}
}
BTW, another thing that is not working if the following logic:
i != j &&
i != k &&
j != k &&
You can see by the outputArr that this logic is being completely ignored.
REFACTORED: even though the online test marked my solution as wrong, you can see with the results, that it is correct. Especially when you factor in the conditionals for making sure that nums[i] != nums[j] and so forth:
const threeSum = (nums) => {
let numsLength = nums.length;
let tempArr = [];
let outputArr = [];
for (let i = 0; i < numsLength; i++) {
for (let j = 0; j < numsLength; j++) {
for (let k = 0; k < numsLength; k++) {
if (
nums[i] != nums[j] &&
nums[i] != nums[k] &&
nums[j] != nums[k] &&
nums[i] + nums[j] + nums[k] == 0
) {
if (typeof outputArr[0] != 'undefined') {
/**********
* if it reaches this conditional
* then outputArr has at least one element
***********/
if (typeof outputArr[k] != 'undefined') {
tempArr[0] = nums[i];
tempArr[1] = nums[j];
tempArr[2] = nums[k];
if (isEqualArr(tempArr, outputArr)) {
// do nothing because there is already an element within the array
} else {
outputArr.push(tempArr);
// empty tempArr after insert
tempArr = [];
}
}
} else {
// push triplet elements into temp array for the first iteration only
tempArr[0] = nums[i];
tempArr[1] = nums[j];
tempArr[2] = nums[k];
// insert tempArr for the first iteration only
outputArr.push(tempArr);
// empty tempArr after insert
tempArr = [];
}
}
}
}
}
return outputArr;
};
const isEqualArr = (a, b) => {
for (elem in b) {
for (let i = 0; i < a.length; i++) {
if (a[i] != elem[i]) {
// do nothing
} else {
return true;
}
}
}
return false;
};
RESULTS:
(3) [Array(3), Array(3), Array(3)]
0: (3) [-1, 0, 1]
1: (3) [1, 0, -1]
2: (3) [-1, 1, 0]
length: 3

Your inner for loop is confusing, if you replace it by a forEach you can see what's going on, you should pass as argument outputArr[x] not [outputArr[x]] and there's more stuff.
const threeSum = (nums) => {
let numsLength = nums.length;
let tempArr = [];
let outputArr = [];
if(numsLength < 3) return;
for (let i = 0; i < numsLength; i++) {
for (let j = 1; j < numsLength; j++) {
for (let k = 2; k < numsLength; k++) {
if (
i != j &&
i != k &&
j != k &&
nums[i] + nums[j] + nums[k] == 0
) {
tempArr.push(nums[i], nums[j], nums[k]); // push three at the same time, it's cleaner and avoid problems
outputArr.forEach((arr, index) => {
if(!isEqualArr(arr, outputArr[index])) outputArr.push(tempArr); // outputs correctly
});
if (i == 0) {
outputArr.push(tempArr);
tempArr = [];
}
}
}
}
}
return outputArr;
};
const isEqualArr = (a, b) => {
for (let i = 0; i < a.length; i++) {
if (a[i] != b[i]) {
return false;
}
}
return true;
};
console.log(threeSum([-1,0,1,2,-1,-4]));

Related

Output the array as a string with hyphen without even or odd elements

It almost works properly, but it shouldn't add the last hyphen
function OmitEvenOrOdd(array, evenOrOdd) {
let output = "";
if(evenOrOdd === 'even') {
for(let i = 0; i < array.length; i++) {
if((array[i] % 2 === 0) && (array[i] >= '0' && array[i] <= '9')) {
continue;
}
output += array[i] + "-";
}
}
else {
for(let i = 0; i < array.length; i++) {
if((array[i] % 2 !== 0) && (array[i] >= '0' && array[i] <= '9')) {
continue;
}
output += array[i] + "-";
}
}
return output;
}
Should show as on the picture
function OmitEvenOrOdd(array, evenOrOdd) {
let output = "";
let i = 0;
if (evenOrOdd === 'odd') {
for (i = 0; i < array.length; i++) {
if (i % 2 == 0) {
if (i == array.length-2) {
output += array[i]
} else {
output += array[i] + '-'
}
}
}
} else {
for (i = 0; i < array.length; i++) {
if (i % 2 != 0) {
if (i == array.length-1) {
output += array[i]
} else {
output += array[i] + '-'
}
}
}
}
return output;
}
console.log(OmitEvenOrOdd([1, 'b', 'x', 2, 3, 4], 'odd'))
console.log(OmitEvenOrOdd([1, 'b', 'x', 2, 3, 4], 'even'))
You could just run through the output at the end and omit any last item that is a -
function OmitEvenOrOdd(array, evenOrOdd) {
let output = '';
if (evenOrOdd === 'even') {
for (let i = 0; i < array.length; i++) {
if ((array[i] % 2 === 0) && (array[i] >= '0' && array[i] <= '9')) {
continue;
}
output += array[i] + "-";
}
} else {
for (let i = 0; i < array.length; i++) {
if ((array[i] % 2 !== 0) && (array[i] >= '0' && array[i] <= '9')) {
continue;
}
output += array[i] + "-";
}
}
let tmp = ''
for (let i = 0; i < output.length; i++)
if (!(i === output.length - 1 && output[i] === '-')) tmp += output[i];
return tmp
}
console.log(OmitEvenOrOdd([1, 'b', 'b', 2, 3, 4], 'odd'))
You need to check if the element is the second from last:
if (i < array.length - 2) output += "-";
I tried to change the least amount of code, so that you can still follow. Since most of the work is being done within the if and else statements, you could move those procedures into their own functions.
function omitEven(array) {
let output = "";
for (let i = 0; i < array.length; i++) {
const val = array[i];
if ((val % 2 === 0) && (isFinite(val) && val >= 0 && val <= 9)) {
continue;
}
output += val;
if (i < array.length - 2) output += "-";
}
return output;
}
function omitOdd(array) {
let output = "";
for (let i = 0; i < array.length; i++) {
const val = array[i];
if ((val % 2 !== 0) && (isFinite(val) && val >= 0 && val <= 9)) {
continue;
}
output += val;
if (i < array.length - 2) output += "-";
}
return output;
}
function OmitEvenOrOdd(array, evenOrOdd) {
if (evenOrOdd === 'even') return omitEven(array);
else return omitOdd(array);
}
console.log(OmitEvenOrOdd([1, 'b', 'x', 2, 3, 4], 'even')); // 1-b-x-3
console.log(OmitEvenOrOdd([1, 'b', 'x', 2, 3, 4], 'odd')); // b-x-2-4
Your program can be optimized by chaining a filter with a join. You could even xor the boolean isEven flag with the result of an even check.
const xor = (a, b) => ( a || b ) && !( a && b );
const evenOrOdd = (arr, isEven) =>
arr
.filter(val =>
isFinite(val)
? xor(val % 2 === 0, isEven)
: true)
.join('-')
console.log(evenOrOdd([1, 'b', 'x', 2, 3, 4], true)); // 1-b-x-3
console.log(evenOrOdd([1, 'b', 'x', 2, 3, 4], false)); // b-x-2-4
function OmitEvenOrOdd(array, evenOrOdd) {
const output = [];
const odd = (num) => isNaN(num) || (num % 2 === 0) ? num : ''
const even = (num) => isNaN(num) || (num % 2 !== 0) ? num : ''
let fnObj = {
odd,
even
};
for (let i = 0; i < array.length; i++) {
if (fnObj[evenOrOdd](array[i])) {
output.push(array[i]);
}
}
return output.join('-');
}
console.log(OmitEvenOrOdd([1, 'b', 'x', 2, 3, 4], 'odd')); //Output: b-x-2-4
console.log(OmitEvenOrOdd([1, 'b', 'x', 2, 3, 4], 'even')); //Output: 1-b-x-3
you can also add one more if else condition for array.length-1
function OmitEvenOrOdd(array, evenOrOdd) {
let output = "";
if(evenOrOdd === 'even') {
for(let i = 0; i < array.length; i++) {
if((array[i] % 2 === 0) && (array[i] >= '0' && array[i] <= '9')) {
continue;
}
if(i === array.length-1){
output += array[i];
}
else{
output += array[i] + "-";
}
}
}
else {
for(let i = 0; i < array.length; i++) {
if((array[i] % 2 !== 0) && (array[i] >= '0' && array[i] <= '9')) {
continue;
}
if(i === array.length-1){
output += array[i];
}
else{
output += array[i] + "-";
}
}
}
return output;
}
console.log(OmitEvenOrOdd([1,'b','x',2,3,4], 'odd'))
or either you can do it by returning the sliced string
return output.slice(0, output.length-1);

Debugging Error on counting empty squares

Given an array of arrays, count how many are empty. Notes: empty counts as: length of 0 (no elements), empty strings, and the number 0.
var squares1 = [[5], [0], [9], ['','', 10]];
console.log(emptySquares(squares1)) //=> 1
var squares2 = [[],[0, ''],[]];
console.log(emptySquares(squares2)) // => 3;
var squares3 = [['hello', 2], ['maybe'], ['10'], [100]];
console.log(emptySquares(squares3)); //=> 0
function emptySquares(squares) {
var total = 0;
for (var i = 0; i < squares.length; i++) {
var isEmpty = true;
for (var j = 0; j < squares[i].length; j++) {
if (squares[i][j] !== '' || squares[i][j] !== 0 || squares[i].length === 0) {
isEmpty = false;
}
}
if (isEmpty) {
total += 1;
}
}
return total;
}
Not exactly sure about the question, but I would go with a simple recursive design:
const emptySquares = (()=>{
let total = 0, a;
return squares=>{
for(let v of squares){
a = v instanceof Array;
if(a && v.length){
total = emptySquares(v);
}
else if(a || v === '' || v === 0){
total++;
}
}
const r = total;
total = 0;
return r;
}
})();
const squares1 = [[5], [0], [9], ['','', 10]];
console.log(emptySquares(squares1));
const squares2 = [[],[0, ''],[]];
console.log(emptySquares(squares2));
const squares3 = [['hello', 2], ['maybe'], ['10'], [100]];
console.log(emptySquares(squares3));

how to get the count value based on comparing string in javascript

I have array object in which I compare each string in a array and if one letter is not matching, increment the value. If three characters match with the string then increment the count value, else 0
var obj = ["race", "sack", "grass", "brass", "beat", "pack", "cake"]
fucntion getValue(obj) {
var count = 0
for (var i = 0; i <= obj.length; i++) {
for (var j = 1; j <= obj.length; j++) {
if (obj[i].split("") == obj[j].split("") {
count++;
}
}
}
}
Expected Output
race 1
sack 2 // (pack, cake matches 3 letters with sack so 2)
grass 1
brass 1
beat 0
pack 2
cake 3
function getSameCount(str1, str2) {
let count = 0;
const obj = str2.split("");
for(str of str1){
let idx = obj.findIndex(s => s === str);
if(idx >= 0){
count++;
obj.splice(idx, 1);
}
}
return count;
}
var obj = ["race", "sack", "grass", "brass", "beat", "pack", "cake"]
const res = {}
for (var i = 0; i < obj.length; i++) {
res[obj[i]] = 0
for (var j = 0; j < obj.length; j++) {
if (i != j) {
matchCount = getSameCount(obj[i], obj[j])
if (matchCount === 3) {
res[obj[i]]++
} else {
if (obj[i].length - matchCount == 1) {
res[obj[i]]++
}
}
}
}
}
console.log(res)
You can create an object for output,
parse through each element in the array, replace characters from comparing elements.
check if at least 3 chars got removed if so +1 to respective element.
const arr = ["race", "sack", "grass", "brass", "beat", "pack", "cake"];
const out = Object.fromEntries(arr.map(e => [e, 0]));
for(i in arr) {
for(j in arr) {
if(i == j) continue;
if(arr[i].length !== arr[j].length) continue;
const res = [...arr[i]].reduce((acc, e)=> acc.replace(e, ''), arr[j]);
if(res.length <= arr[j].length - 3) {
out[arr[i]] = out[arr[i]] + 1
}
}
}
console.log(out);

CodeWars/ Merged String Checker

The challenge is next:
At a job interview, you are challenged to write an algorithm to check if a given string, s, can be formed from two other strings, part1 and part2.
The restriction is that the characters in part1 and part2 are in the same order as in s.
The interviewer gives you the following example and tells you to figure out the rest from the given test cases.
What am I doing wrong? Why it fails anyway?
I wrote 2 different scripts, and both aren't working for some test cases
function isMerge(s, part1, part2) {
var sArr = s.split('');
var part1Arr = part1.split('');
var part2Arr = part2.split('');
var tempArr = new Array(sArr.length);
function compareArrays(arr1, arr2){
var count = 0;
for (var i = 0; i < arr1.length; i++) {
if (arr1[i] !== arr2[i]) count++;
}
return (count == 0);
}
for (var i = 0; i < sArr.length; i++) {
for (var j = 0; j < part1Arr.length; j++) {
if (sArr[i] == part1Arr[j]) tempArr[i] = j;
}
for (var k = 0; k < part2Arr.length; k++) {
if (sArr[i] == part2Arr[k]) tempArr[i] = k;
}
}
alert(tempArr);
var check = tempArr.slice();
check.sort();
alert(check);
if (compareArrays(tempArr, check)) return true;
else return false;
}
alert(isMerge('codewars', 'cdw', 'oears'));
function isMerge(s, part1, part2) {
// create arrays of letters
var sArr = s.split('');
var part1Arr = part1.split('');
var part2Arr = part2.split('');
// create an associative array 'temp' (0:C, 1:O and so on)
var temp = {};
for (var k = 0; k < sArr.length; k++) {
temp[k] = sArr[k];
}
// reverse an associative array 'temp' (now C:0, O:0 and so on)
for (var key in temp) {
var keyTemp = key;
var keyValue = temp[key];
key = keyValue;
temp[key] = keyTemp;
}
// the function that compares arrays
function compareArrays(arr1, arr2){
var count = 0;
for (var i = 0; i < arr1.length; i++) {
if (arr1[i] !== arr2[i]) count++;
}
return (count == 0);
}
// sorting function
function order(a, b) {
var comparingA;
var comparingB;
for (var char in temp) {
if (char == a) {
comparingA = temp[char]; // comparingA is the number of 'a' in object 'temp'
}
if (char == b){
comparingB = temp[char]; // comparingB is the number of 'b' in object 'temp'
}
}
return (comparingA - comparingB);
}
// create copies of arrays
var part1Sorted = part1Arr.slice();
var part2Sorted = part2Arr.slice();
// and sort that copies
part1Sorted.sort(order);
part2Sorted.sort(order);
// If the array did not change after sorting, the order of the letters was correct
if (compareArrays(part1Sorted, part1Arr) && compareArrays(part2Sorted, part2Arr)) {
// so now we can check is merge possible
sArr = sArr.sort();
var parts = part1Arr.concat(part2Arr);
parts = parts.sort();
var res = compareArrays(sArr, parts);
return res;
}
return false;
}
alert(isMerge('codewars', 'code', 'wasr'));
alert(isMerge('codewars', 'oers', 'cdwa'));
I just added comments to the second script
I find it hard to understand what your code is attempting to do. It would help if you provided comments as well as explain the idea behind the algorithm/s you are attempting to implement.
Here's a commented example of a recursion that considers if pointers i and j to parts 1 & 2 could constitute a valid merge up to that point.
function isMerge(s, part1, part2) {
// Merge is invalid if the parts' lengths don't add up to the string's
if (part1.length + part2.length != s.length)
return false;
// Recursive function
function g(i, j){
// Base case: both pointers are exactly at the end of each part
if (i == part1.length && j == part2.length)
return true;
// One of our pointers has extended beyond the part's length,
// that couldn't be right
if (i > part1.length || j > part2.length)
return false;
// Just part1 matches here so increment i
if (part1[i] == s[i + j] && part2[j] != s[i + j])
return g(i + 1, j);
// Just part2 matches here so increment j
else if (part1[i] != s[i + j] && part2[j] == s[i + j])
return g(i, j + 1);
// Both parts match here so try incrementing either pointer
// to see if one of those solutions is correct
else if (part1[i] == s[i + j] && part2[j] == s[i + j])
return g(i + 1, j) || g(i, j + 1);
// Neither part matches here
return false;
}
// Call the recursive function
return g(0,0);
}
console.log(isMerge('codewars', 'cdw', 'oears'));
console.log(isMerge('codecoda', 'coda', 'code'));
console.log(isMerge('codewars', 'oers', 'cdwa'));
console.log(isMerge('codewars', 'cdw', 'years'));
Stack version for really long strings:
function isMerge2(s, part1, part2) {
if (part1.length + part2.length != s.length)
return false;
let stack = [[0,0]];
while (stack.length){
[i, j] = stack.pop();
if (i == part1.length && j == part2.length)
return true;
if (i > part1.length || j > part2.length)
continue;
if (part1[i] == s[i + j] && part2[j] != s[i + j])
stack.push([i + 1, j]);
else if (part1[i] != s[i + j] && part2[j] == s[i + j])
stack.push([i, j + 1]);
else if (part1[i] == s[i + j] && part2[j] == s[i + j]){
stack.push([i + 1, j]);
stack.push([i, j + 1]);
}
}
return false;
}
function test(){
let s = '';
for (let i=0; i<1000000; i++)
s += ['a','b','c','d','e','f','g'][~~(Math.random()*6)];
let lr = {
l: '',
r: ''
};
for (let i=0; i<s.length; i++){
let which = ['l', 'r'][~~(Math.random()*2)];
lr[which] += s[i];
}
console.log(isMerge2(s,lr.l,lr.r));
}
test();
This is a recursive approach: it checks for a match of the first character of the string with either of the parts, and if there's a match recurses to try and match the rest of the string with the rest of the parts. The tricky thing is that when the first character of both parts is the same, you have to check if you can match against either of them (this solves the Bananas test).
function isMerge(str, p1, p2) {
if (!str.length) return !p1.length && !p2.length;
if (p1.length && str.charAt(0) == p1.charAt(0)) {
if (p2.length && str.charAt(0) == p2.charAt(0)) {
return isMerge(str.substr(1), p1.substr(1), p2) || isMerge(str.substr(1), p1, p2.substr(1));
}
else {
return isMerge(str.substr(1), p1.substr(1), p2);
}
}
else if (p2.length && str.charAt(0) == p2.charAt(0)) {
return isMerge(str.substr(1), p1, p2.substr(1));
}
else {
return false;
}
}
Recursive Call:
You could use a recursive approach by first checking the length of string and part strings and then by the length or by checking a character and by checking the rest of the given part strings.
function isMerge(s, part1, part2) {
if (s.length !== part1.length + part2.length) {
return false;
}
if (!s.length) {
return true;
}
if (part1[0] === s[0] && isMerge(s.slice(1), part1.slice(1), part2)) {
return true;
}
if (part2[0] === s[0] && isMerge(s.slice(1), part1, part2.slice(1))) {
return true;
}
return false;
}
console.log(isMerge('codewars', 'cdw', 'oears')); // true
console.log(isMerge('codewars', 'oers', 'cdwa')); // true
console.log(isMerge('codecoda', 'coda', 'code')); // true
console.log(isMerge('baeabb', 'b', 'baeab')); // true
console.log(isMerge('bdab', 'bdab', '')); // true
console.log(isMerge('bfaef', 'f', 'bfae')); // true
console.log(isMerge('codewars', 'cdw', 'years')); // false
console.log(isMerge('codewars', 'code', 'warss')); // false
console.log(isMerge('codewars', 'codes', 'wars')); // false
console.log(isMerge('', 'a', 'b')); // false
.as-console-wrapper { max-height: 100% !important; top: 0; }
With a Stack instead of a Recursive Call:
function isMerge(s, part1, part2) {
var stack = [[s, part1, part2]];
if (s.length !== part1.length + part2.length) {
return false;
}
while (stack.length) {
[s, part1, part2] = stack.shift();
if (!s.length) {
return true;
}
if (part1[0] === s[0]) {
stack.push([s.slice(1), part1.slice(1), part2]);
}
if (part2[0] === s[0]) {
stack.push([s.slice(1), part1, part2.slice(1)]);
}
}
return false;
}
console.log(isMerge('codewars', 'cdw', 'oears')); // true
console.log(isMerge('codewars', 'oers', 'cdwa')); // true
console.log(isMerge('codecoda', 'coda', 'code')); // true
console.log(isMerge('baeabb', 'b', 'baeab')); // true
console.log(isMerge('bdab', 'bdab', '')); // true
console.log(isMerge('bfaef', 'f', 'bfae')); // true
console.log(isMerge('codewars', 'cdw', 'years')); // false
console.log(isMerge('codewars', 'code', 'warss')); // false
console.log(isMerge('codewars', 'codes', 'wars')); // false
console.log(isMerge('', 'a', 'b')); // false
.as-console-wrapper { max-height: 100% !important; top: 0; }
May you try this below?
function isMerge(s, part1, part2) {
var result= true;
var total = part1 + part2;
for (var i = 0; i < s.length; i++) {
var char = s.charAt(i);
if(total.indexOf(char) === -1) {
result = false;
break;
}
}
return result;
}
First of all, here is your code just working:
function isMerge(s, part1, part2) {
var sArr = s.split('');
var part1Arr = part1.split('');
var part2Arr = part2.split('');
var tempArr = new Array(sArr.length);
function compareArrays(arr1, arr2){
var count = 0;
for (var i = 0; i < arr1.length; i++) {
if (arr1[i] != arr2[i]) count++;
}
return (count == 0);
}
for (var i = 0; i < sArr.length; i++) {
for (var j = 0; j < part1Arr.length; j++) {
if (sArr[i] == part1Arr[j]) tempArr[i] = part1Arr[j];
}
for (var k = 0; k < part2Arr.length; k++) {
if (sArr[i] == part2Arr[k]) tempArr[i] = part2Arr[k];
}
}
alert(tempArr);
if (compareArrays(tempArr, sArr)) return true;
else return false;
}
alert(isMerge('codewars', 'cdw', 'oears'));
Now, what was the problem?
for (var j = 0; j < part1Arr.length; j++) {
/* Here you assigned the index (tempArr[i] = j;) not the char */
if (sArr[i] == part1Arr[j]) tempArr[i] = part1Arr[j];
}
for (var k = 0; k < part2Arr.length; k++) {
/* Here you assigned the index (tempArr[i] = k;) not the char */
if (sArr[i] == part2Arr[k]) tempArr[i] = part2Arr[k];
}
Hope i could help you ;)
Simple merge logic:
function isMerge(s, part1, part2) {
var sArr = s.split('');
var part1Arr = part1.split('');
var part2Arr = part2.split('');
var j = 0;
var k = 0;
for (var i = 0; i < sArr.length; i++) {
if ((j < part1Arr.length) && (sArr[i] == part1Arr[j]))
j++
else if ((k < part2Arr.length) && (sArr[i] == part2Arr[k]))
k++
else
break
}
return (j == part1Arr.length && k == part2Arr.length && (j + k) == sArr.length);
}
console.log(isMerge('abcd', 'ac', 'bd'));
console.log(isMerge('abcd', 'acd', 'b'));
console.log(isMerge('abcd', 'ac', 'b'));
console.log(isMerge('abcd', 'ac', 'db'));
console.log(isMerge('abcd', 'c', 'b'));
console.log(isMerge('a', '', 'a'));
console.log(isMerge('', '', ''));
console.log(isMerge('', 'a', 'b'));
console.log(isMerge('ab', '', ''));

Why is this happening with javascript objects

I am working on a function to map a string that has been split into an array
function arrayDups(a) // a: array to search: as in string split into array.
{
var unique = {}
var dups = [];
var seen = false;
var bypass = {};
for(var i = 0; i < a.length; i++)
{
if(bypass[a[i]] == 'undefined')
{
unique[a[i]] = i+',';
bypass[a[i]] = false;
}
for(var k = i; k < a.length; k++)
{
// so the same char later will not produce duplicate records.
if(unique[a[k]] != 'undefined' && bypass[a[k]] != 'undefined' && !bypass[a[k]])
{
unique[a[k]] += k+',';
if(k == a.length - 1)
{
bypass[a[i]] = true
}
}
}
}
for(var x in unique)
{
dups[dups.length] = x+':'+unique[x]
}
return dups;
}
this is colled in the following context
var testCase = ('disproportionate').split('');
window.onload = function()
{
var test = document.getElementById('res')
test.childNodes[0].data = arrayDups(testCase).join("\n")
}
which produces the following output
d:undefined0,
i:undefined1,10,1,10,
s:undefined2,2,2,
p:undefined3,6,3,6,3,6,3,6,
r:undefined4,8,4,8,4,8,4,8,4,8,
o:undefined5,7,11,5,7,11,5,7,11,5,7,11,5,7,11,5,7,11,
t:undefined9,14,9,14,9,14,9,14,9,14,9,14,9,14,9,14,9,14,9,14,
n:undefined12,12,12,12,12,12,12,12,12,12,12,12,12,
a:undefined13,13,13,13,13,13,13,13,13,13,13,13,13,13,
e:undefined15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
The questions:
where is undefined coming from
and why are the index positions being duplicated when for each iteration of i
k begins at the current i value and should be looking ahead to find index values of duplicate chars
I wouldn't want to answer my own question so I am adding to the original post via edits
Here is what I came up with
function arrayDups(a) // a: array to search: as in string split into array.
{
var unique = {}
var dups = [];
var seen = false;
var bypass = {};
for(var i = 0; i < a.length; i++)
{
if(!bypass.propertyIsEnumerable(a[i]))
{
unique[a[i]] = i+',';
bypass[a[i]] = 'false';
continue;
}
if(bypass.propertyIsEnumerable(a[i]) && bypass[a[i]] == 'false')
{
for(var k = i; k < a.length; k++)
{
// for every instance of a[i] == a[k] unique[a[k]] will be defined
if(a[i] == a[k] && unique.propertyIsEnumerable(a[k]))
{
unique[a[k]] += k+',';
}
if(k == a.length - 1)
{
bypass[a[i]] = 'true'
continue;
}
}
}
}
for(var x in unique)
{
dups[dups.length] = x+':'+unique[x]
}
return dups;
}
And this is the output
d:0,
i:1,10,
s:2,
p:3,6,
r:4,8,
o:5,7,11,
t:9,14,
n:12,
a:13,
e:15,
so now all I have to do is strip the railing ','

Categories

Resources