EndOfTheGlory
EndOfTheGlory

Reputation: 309

How to adjust return values of map() function?

I have been trying to make a excercise in the course I am taking. At the end, I did what was asked, but I personally think I overdid too much and the output is not convenient -- it's a nested array with some blank arrays inside... I tried to play with return, but then figured out the problem was in the function I used: map always returns an array. But all other functions, which are acceptable for arrays (in paticular forEach and I even tried filter) are not giving the output at all, only undefined. So, in the end, I have to ask you how to make code more clean with normal output like array with just 2 needed numbers in it (I can only think of complex way to fix this and it'll add unneeded junk to the code).

Information

Task:

Write a javascript function that takes an array of numbers and a target number. The function should find two different numbers in the array that, when added together, give the target number. For example: answer([1,2,3], 4) should return [1,3]

Code

const array1 = [1, 2, 3];
const easierArray = [1, 3, 5] //Let's assume number we search what is the sum of 8

const findTwoPartsOfTheNumber = ((arr, targetNum) => {
  const correctNumbers = arr.map((num, index) => {
    let firstNumber = num;
    // console.log('num',num,'index',index);
    const arrayWeNeed = arr.filter((sub_num, sub_index) => {
      // console.log('sub_num',sub_num,'sub_index',sub_index);
      if (index != sub_index && (firstNumber + sub_num) === targetNum) {
        const passableArray = [firstNumber, sub_num] //aka first and second numbers that give the targetNum
        return sub_num; //passableArray gives the same output for some reason,it doesn't really matter.
      }
    })
    return arrayWeNeed
  })


  return correctNumbers;
  // return `there is no such numbers,that give ${targetNum}`;
})

console.log(findTwoPartsOfTheNumber(easierArray, 8));
console.log(findTwoPartsOfTheNumber(array1, 4));

Output

[[],[5],[3]]

for the first one

Upvotes: 3

Views: 199

Answers (5)

max890
max890

Reputation: 527

Map and filter are nice functions to have if you know that you need to loop into the whole array. In your case this is not necessary.

So you know you need to find two numbers, let's say X,Y, which belong to an array A and once added will give you the target number T.

Since it's an exercise, I don't want to give you the working code, but here is a few hints:

  • If you know X, Y must be T - X. So you need to verify that T - X exists in your array.
  • array.indexOf() give you the position of an element in an array, otherwise -1
  • If X and Y are the same number, you need to ensure that their index are not the same, otherwise you'll return X twice
  • Returning the solution should be simple as return [X,Y]

So this can be simplified with a for (let i = 0; i < arr.length; i++) loop and a if statement with a return inside if the solution exist. This way, if a solution is found, the function won't loop further.

After that loop, you return [] because no solution were found.

EDIT:

Since you want a solution with map and filter:

findTwoPartsOfTheNumber = (arr, tNumber) => {
    let solution = [];

    arr.map((X, indexOfX) => {
        const results = arr.filter((Y, indexOfY) => {
            const add = Y + X
            if (tNumber === add && indexOfX != indexOfY) return true;
            else return false;
        });

        if (results > 0) solution = [X, results[0]];
    })

    return solution;
}

Upvotes: 0

alex067
alex067

Reputation: 3301

You can also add all the values in the array to find the total, and subtract the total by the target to find the value you need to remove from the array. That will then give you an array with values that add up to the total.

let arr1 = [1, 3, 5]
const target = 6

const example = (arr, target) => {
  let total = arr.reduce((num1, num2) => {
    return num1 + num2
  })
  total = total - target
  const index = arr.indexOf(total)
  if (index > -1) {
    return arr.filter(item => item !== total)
  }
}

console.log(example(arr1, target))

Upvotes: 0

Herohtar
Herohtar

Reputation: 5613

There doesn't appear to be any requirement for using specific array functions (map, forEach, filter, etc) in the problem statement you listed, so the code can be greatly simplified by using a while loop and the fact that you know that the second number has to be equal to target - first (since the requirement is first + second == target that means second == target - first). The problem statement also doesn't say what to do if no numbers are found, so you could either return an empty array or some other value, or even throw an error.

const answer = (list, target) => {
  while (list.length > 0) { // Loop until the list no longer has any items
    let first = list.shift() // Take the first number from the list
    let second = target - first // Calculate what the second number should be
    if (list.includes(second)) { // Check to see if the second number is in the remaining list
      return [first, second] // If it is, we're done -- return them
    }
  }
  
  return "No valid numbers found" // We made it through the entire list without finding a match
}

console.log(answer([1,2,3], 3))
console.log(answer([1,2,3], 4))
console.log(answer([1,2,3], 7))

Upvotes: 1

Taki
Taki

Reputation: 17654

You can clean up the outpu by flatting the returned arrays :

return arrayWeNeed.flat(); 

and

return correctNumbers.flat();

const array1 = [1, 2, 3];
const easierArray = [1, 3, 5] //Let's assume number we search what is the sum of 8

const findTwoPartsOfTheNumber = ((arr, targetNum) => {
  const correctNumbers = arr.map((num, index) => {
    let firstNumber = num;
    // console.log('num',num,'index',index);
    const arrayWeNeed = arr.filter((sub_num, sub_index) => {
      // console.log('sub_num',sub_num,'sub_index',sub_index);
      if (index != sub_index && (firstNumber + sub_num) === targetNum) {
        const passableArray = [firstNumber, sub_num] //aka first and second numbers that give the targetNum
        return sub_num; //passableArray gives the same output for some reason,it doesn't really matter.
      }
    })
    
    return arrayWeNeed.flat(); 
  })


  return correctNumbers.flat();
  // return `there is no such numbers,that give ${targetNum}`;
})

console.log(findTwoPartsOfTheNumber(easierArray, 8));
console.log(findTwoPartsOfTheNumber(array1, 4));

However, using a recursive function could be simpler :

const answer = (arr, num) => {
  if (arr.length < 1) return;

  const [first, ...rest] = arr.sort();

  for (let i = 0; i < rest.length; i++) {
    if (first + rest[i] === num) return [first, rest[i]];
  }

  return answer(rest, num);
};

console.log(answer([1, 2, 3], 4));
console.log(answer([1, 3, 5], 8));

Upvotes: 2

guijob
guijob

Reputation: 4488

It looks like you are trying to leave .map() and .filter() beforehand, which you can't (without throwing an error). So I suggest a normal for approach for this kind of implementation:

const array1 = [1,2,3];
const easierArray = [1,3,5] //Let's assume number we search what is the sum of 8

const findTwoPartsOfTheNumber = (arr,targetNum) =>{
    for(let index = 0; index < arr.length; index++) {
        let firstNumber = arr[index];
        // console.log('num',num,'index',index);
        for(let sub_index = 0; sub_index < arr.length; sub_index++){
          const sub_num = arr[sub_index];
            // console.log('sub_num',sub_num,'sub_index',sub_index);
            if (index != sub_index && (firstNumber + sub_num) === targetNum){
                const passableArray = [firstNumber,sub_num]//aka first and second numbers that give the targetNum
                return passableArray; //passableArray gives the same output for some reason,it doesn't really matter.
            }
        }
    }


    return `there is no such numbers,that give ${targetNum}`;
}

console.log(findTwoPartsOfTheNumber(easierArray,8));
console.log(findTwoPartsOfTheNumber(array1,4));
console.log(findTwoPartsOfTheNumber(array1,10));

I've just grab your code and changed map and filter to for implementation.

Upvotes: 1

Related Questions