4

I have an assignment where I am supposed to check two arrays (unsorted) with integers, to see if

  1. They have the same length
  2. The first element contains integers and the second has the same values squared, in any order

For example:

test([5,4,1], [1,16,25]) // would return true ..

What I've done so far is first sort the two input arrays, and then compare the length. Once we confirm the length is the same we iterate through each value to make sure they're equal. Keep in mind I haven't gotten to comparing the values to their squared counterpart yet, because my loop is not giving me expected results. Here is the code:

function test(arr1, arr2){
  // sort arrays
  const arr1Sort = arr1.sort(),
        arr2Sort = arr2.sort();

  // compare length and then compare values
  if(arr1Sort.length === arr2Sort.length) {
    for(let i = 0; i < arr1Sort.length; i++) {
      if(arr1Sort[i] === arr2Sort[i]) {
        return true;
      } else {
        return false;
      }
    }
  }
}

console.log(test([1,2,3], [1,5,4])); returns true but the array values are different?!
4
  • turn your if around return false if its not equal and only return true if it got through the entire array Commented Jun 29, 2019 at 0:38
  • also turn the length comparison around imediadetly return false if they are of different length Commented Jun 29, 2019 at 0:39
  • Are duplicate numbers in the input arrays allowed? Commented Jun 29, 2019 at 0:39
  • @CertainPerformance: Yes duplicate numbers are allowed. Thank you! Commented Jun 29, 2019 at 0:40

2 Answers 2

3

Inside the for, no matter whether the if or else is fulfilled, the function will immediately return true or false on the first iteration - it'll never get past index 0. To start with, return true only after the loop has concluded, and return false if arr1Sort[i] ** 2 !== arr2Sort[i] (to check if the first squared equals the second).

Also, when sorting, make sure to use a callback function to compare each item's difference, because otherwise, .sort will sort lexiographically (eg, [1, 11, 2]):

function comp(arr1, arr2){
  // sort arrays
  const sortCb = (a, b) => a - b;
  const arr1Sort = arr1.sort(sortCb),
      arr2Sort = arr2.sort(sortCb);

  // compare length and then compare values
  if(arr1Sort.length !== arr2Sort.length) {
    return false;
  }
  for(let i = 0; i < arr1Sort.length; i++) {
    if(arr1Sort[i] ** 2 !== arr2Sort[i]) {
      return false;
    }
  }
  return true;
}

console.log(comp([1,2,3], [1,5,4]));
console.log(comp([5,4,1], [1,16,25]));

You can decrease the computational complexity to O(N) instead of O(N log N) by turning arr2 into an object indexed by the squared number beforehand:

function comp(arr1, arr2){
  if (arr1.length !== arr2.length) {
    return false;
  }
  const arr2Obj = arr2.reduce((a, num) => {
    a[num] = (a[num] || 0) + 1;
    return a;
  }, {});
  for (let i = 0; i < arr1.length; i++) {
    const sq = arr1[i] ** 2;
    if (!arr2Obj[sq]) {
      return false;
    }
    arr2Obj[sq]--;
  }
  return true;
}

console.log(comp([1,2,3], [1,5,4]));
console.log(comp([5,4,1], [1,16,25]));

(if duplicates weren't permitted, this would be a lot easier with a Set instead, but they are, unfortunately)

Sign up to request clarification or add additional context in comments.

5 Comments

Amazing answer .. makes total sense, thank you! I kinda figured this was happening I just didn't know how to return true once the loop completed, this shows me how, perfect!
Is it me or is the first answer not working if both inputs are unordered?
It works for me using comp([5,4,1], [25,1,16]), can you give an example?
I think it's because of the .sort() without a callback (which compares lexiographically), change to check the difference between the two items compared
Very nice, working as expected! So in this case we need to provide the callback for .sort() ..
1

This should work, no mater the data to compare:

function similar(needle, haystack, exact){
  if(needle === haystack){
    return true;
  }
  if(needle instanceof Date && haystack instanceof Date){
    return needle.getTime() === haystack.getTime();
  }
  if(!needle || !haystack || (typeof needle !== 'object' && typeof haystack !== 'object')){
    return needle === haystack;
  }
  if(needle === null || needle === undefined || haystack === null || haystack === undefined || needle.prototype !== haystack.prototype){
    return false;
  }
  var keys = Object.keys(needle);
  if(exact && keys.length !== Object.keys(haystack).length){
    return false;
  }
  return keys.every(function(k){
    return similar(needle[k], haystack[k]);
  });
}
console.log(similar(['a', {cool:'stuff', yes:1}, 7], ['a', {cool:'stuff', yes:1}, 7], true));
// not exact
console.log(similar(['a', {cool:'stuff', yes:1}, 7], ['a', {cool:'stuff', stuff:'more', yes:1}, 7, 'more stuff only at the end for numeric array']));

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.