0

I have an array of thread objects like this

threadlist:Thread[]= [thread{id:1},thread{id:2},thread{id:3},...]

I also have a ThreadRelation array inside a user object like below to store if the user has a certain thread bookmarked or not. Please note that the id in Thread does not match its place in the array.

user{
  user_id:number,...(some other user typical properties)
  threadRelations:ThreadRelation[]=[
  threadRelation{
    id:2,//relates to id property of a Thread object
    isBookmarked:true
  },
  threadRelation{
    id:18,
    isBookmarked:true
  },..
]}

I want to create a function which returns an array with only bookmarked threads of a user. I can achieve this using two for-loops and if-statements, but i don't think its efficient.. Is there some methods where i can find that specific object inside the array directly?

updateBookmarkedList(){
      for (var i = 0; i < this.activeUser.threadsRelation.length; i++){
        if ( this.activeUser.threadsRelation[i].bookmarked == true){
          var searchId = this.activeUser.threadsRelation[i].id;
          for (var j = 0; j < this.threadlist.length; j++){
            if (this.threadlist[j].id == searchId){
              this.userBookmarkedList.push(this.threadlist[j])
            }
          }
        }
      }
  }

Thanks!

2
  • 1
    Use Array.prototype.filter! A side note, your JSON is invalid, unless this is pseudo code. In which case, you should provide a full example of what you have (with valid data). Commented Apr 6, 2016 at 12:48
  • @Mr.Polywhirl Consider making this an answer. Commented Apr 6, 2016 at 13:23

3 Answers 3

1

If Thread.id is a unique identifier, then you really should use a Map instead of an Array of objects with no keys. Without keys you will have to iterate the arrays with no other choices.

When iterating an Array, try to use built in iteration methods like forEach. They are more efficient and looks neater than loops.

To make a supplement to @Tamas-Hegedus's answer using ES6 iterator feature, I created a JSFiddle using current version of JavaScript to make a "Array-Map", you can replace it with Map if Thread.id is not numeric.

See JSFiddle.

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

Comments

1

Why don't you keep a map of the "threads" by their id?

To create the map from the array:

var threadsById = new Map(threads.map(t => [t.id, t]));

To get if a threadid is present:

if (threadsById.has(threadRelation.id)) {
  ...
}

To get the thread by its id:

var currentThread = threadsById.get(threadRelation.id);

Comments

1

With Array.prototype.filter, you can keep only the bookmarked thread relationships. From this filtered list, you can build a list of threads based off of the id criteria.

var threads = [
  { id: 1 },
  { id: 2 },
  { id: 3 }
];

var users = [{
  user_id: 1,
  threadRelations: [
    { id: 2,  isBookmarked: true },
    { id: 18, isBookmarked: true }
  ]
}];

var userBookmarkedList = updateBookmarkedList(users[0], threads);
document.body.innerHTML = '<pre>Threads -> ' + JSON.stringify(userBookmarkedList, null, 2) + '</pre>';

function updateBookmarkedList(user, threads) {
  return user.threadRelations.filter(function(threadRelation) {
    return threadRelation.isBookmarked === true;
  }).reduce(function(list, threadRelation) {
    return list.concat(threads.filter(function(thread) {
      return thread.id === threadRelation.id;
    }));
  }, []);
}

You could also create a map, to improve lookup performance.

var threads = [
  { id: 1 },
  { id: 2 },
  { id: 3 }
];

var users = [{
  user_id: 1,
  threadRelations: [
    { id: 2,  isBookmarked: true },
    { id: 18, isBookmarked: true }
  ]
}];

var threadMap           = mapBy(threads, 'id');
var userBookmarkedList  = retrieveBookmarkedThreads(users[0], threadMap);
document.body.innerHTML = '<pre>Threads -> ' + JSON.stringify(userBookmarkedList, null, 2) + '</pre>';

function mapBy(list, key) {
  return list.reduce(function(map, item) {
    map[item[key]] = item;
    return map;
  }, {});
}

function retrieveBookmarkedThreads(user, threadMap) {
  return user.threadRelations.filter(function(threadRelation) {
    return threadRelation.isBookmarked === true;
  }).reduce(function(list, threadRelation) {
    return (function(thread) {
      return thread != null ? list.concat(thread) : list;
    }(threadMap[threadRelation.id]));
  }, []);
}

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.