0

I have a small application where I have an array of objects. Each object is a student and each student object has an array of tags that looks like this:

const students = 
  [ { name: "John",   tags: [ 'tag1', 'tag2' ] } 
  , { name: "Leslie", tags: [ 'tag1' ]         } 
  , { name: "Mark",   tags: [ 'tag', 'tag2' ]  }
  ] 

Right now to search for students with the same tags I iterate through the array of objects and array of tags for each student which is O(n) squared.

const filterByTag = (filter) => {
  let result = [];
  initialStudents.map((student) => {
    student.tags.map((tag) => {
      if (tag.includes(filter)) {
        result.push(student);
      }
    });
  });
  return result;
};

How can I reduce time complexity? I was thinking of creating an object with name->tags and then go through it, but it seems to be the same O(n) squared.

3
  • 1
    You can almost always reduce time complexity using a key/value map/dictionnary for lookups. Furthermore, don't use map as forEach. Commented Jul 4, 2021 at 1:00
  • I tried but it seems i will have to go through each key-value and through each value (array) and it's O(n) squared anyways Commented Jul 4, 2021 at 1:26
  • Have a look at the Trie data structure or "Prefix Tree" to create an index. Commented Jul 4, 2021 at 1:32

1 Answer 1

1

I don't think there are any significant gains to be made here, from a complexity standpoint. There's no way around iterating over

  • each student
  • each tag inside each student
  • each character inside each tag string (abstracted behind the .includes)

That requires a significant amount of computational complexity, which you're implementing pretty reasonably already.

But you can make the code a bit better and reduce a bit of unnecessary overhead. Don't use .map for side-effects - for side-effects, use forEach or for..of. But a better approach here would be to use .filter to construct a new array of student objects depending on which pass the test - since you probably only want to push a single student when it matches, rather than that student for every matching tag.

const filterByTag = (filter) => {
    return initialStudents.filter(student => 
        student.tags.some(
            tag => tag.includes(filter)
        )
    );
};

(Only use .map when you're using the result of the call as a new array - eg const mappedArray = originalArray.map(...)

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

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.