My function returns true or false. I made the code, but I think it could be shorter with native js methods

Asked

Viewed 40 times

0

My function returns true or false, did the code, but I think it could be shorter with native javascript methods:

function authorUnique() {
 return books.every((book) => {
    for (let i in book) {
      for (let j in book) {
        if (Object.values(book.author.birthYear)[i] ===
            Object.values(book.author.birthYear)[j]
        ) {
          false;
        } else {
          true;
        }
      }
    }
  })
  • Your title is very badly crafted, and your code really very badly written, making two interaction to compare values, what you really want to do and what is Books you when creating question here need to detail so that we have no doubts, that is, it generated only doubts its question.

  • I appreciate the feedback, and I understand the need to improve the title of the question. I want to avoid these loops, I want to check if in the object array I have 2 authors of the same age. If you can help me, I really appreciate it.

1 answer

2

The every is not the most ideal in this case, it is most indicated when you want to test if all elements of an array validate some predicate.

In that case a bow for with a map to know how many years have already been checked would solve your problem:

function authorUniqueByBirthYear(books) {
  const map = Object.create(null);

  for (const { author } of books) {
    if (map[author.birthYear]) {
      map[author.birthYear]++;
    } else {
      map[author.birthYear] = 1;
    }

    if (map[author.birthYear] === 2) {
      return false;
    }
  }

  return true;
}

console.log(authorUniqueByBirthYear([
  { author: { birthYear: 1 } },
  { author: { birthYear: 2 } },
  { author: { birthYear: 2 } },
  { author: { birthYear: 3 } }
])); // false

console.log(authorUniqueByBirthYear([
  { author: { birthYear: 1 } },
  { author: { birthYear: 2 } },
  { author: { birthYear: 3 } }
])); // true

The logic is simple:

  1. Initiate map as an empty object (we use Object.create(null) for that reason).
  2. For each author of the list of books passed as a parameter, do:
    1. If, in map, the year of birth of the author has already been recorded in map by some previous iteration, add up 1 the count corresponding to the anniversary year of the current iteration.
    2. Otherwise, we start, at map, the value 1 for the author’s birth year of the current iteration.
    3. If the year of birth of the current iteration has a value equal to 2 in map, return false.
  3. Return true (indicates that all authors are unique by date of birth).

So we have a code with complexity O(n), in the worst case.


Have to make the check 2.1 and 2.2 a little more compact in code:

function authorUniqueByBirthYear(books) {
  const map = Object.create(null);

  for (const { author } of books) {
    map[author.birthYear] = (map[author.birthYear] || 0) + 1;

    if (map[author.birthYear] === 2) {
      return false;
    }
  }

  return true;
}

console.log(authorUniqueByBirthYear([
  { author: { birthYear: 1 } },
  { author: { birthYear: 2 } },
  { author: { birthYear: 2 } },
  { author: { birthYear: 3 } }
])); // false

console.log(authorUniqueByBirthYear([
  { author: { birthYear: 1 } },
  { author: { birthYear: 2 } },
  { author: { birthYear: 3 } }
])); // true

Behold more about the OR operator (||) in this type of use.

In short, most of the time we try to use "more sophisticated" methods (such as the every), being that a good old for already solves much more easily. :)

Browser other questions tagged

You are not signed in. Login or sign up in order to post.