1

I am trying to add a value from one object to another if both have the same value.

This is how the objects looks like basically:

var comments = [
  {
    author: '4jdf7s',
    message: 'Comment text here',
    posted: '2014-12-29 14:30'
  },
  {
    author: '87sd3w',
    message: 'Comment text here',
    posted: '2014-12-30 12:00'
  }
];

var users = [
  {
    _id: '87sd3w',
    username: 'MyUsername'
  },
  {
    _id: '4jdf7s',
    username: 'OtherUsername'
  }
];

And as author and _id is the same, I want to add users.username to comments.username like this:

var comments = [
  {
    author: '4jdf7s',
    username: 'OtherUsername',
    message: 'Comment text here',
    posted: '2014-12-29 14:30'
  },
  {
    author: '87sd3w',
    username: 'MyUsername',
    message: 'Comment text here',
    posted: '2014-12-30 12:00'
  }
];

The comments object has been sorted, which is why it can't be scrambled aswell.

This is my current code but it doesn't work at all:

comments.forEach(function(i, index) {
  users.forEach(function(e) {
    if(e._id == i.author) {
      comments[index].username = e.username;
    }
  });
});

2 Answers 2

2

The callback for Array.forEach has the object as the first parameter, not the index. So change to this:

comments.forEach(function(comment) {
    users.forEach(function(user) {
        if (user._id === comment.author) {
            comment.username = user.username;
        }
    });
});

Would like to also point out that nested loops like this are notoriously a bad idea with large sets of data; it has an O(N*M) complexity. In addition, once you find a match, the loop continues. I'd recommend you create a lookup of the users first so that each lookup is an O(1), converting the overall code to O(N):

var usersById = {};
users.forEach(function(user) { usersById[user._id] = user; });

comments.forEach(function(comment) {
    var user = usersById[comment.author];
    if (user) {
        comment.username = user.username;
    }
});
Sign up to request clarification or add additional context in comments.

6 Comments

Thank you for the response! I tried with your code, but it doesn't seem to work either, as this is what I'm getting back when logging comments: [ { author: 54a34906af18e2a3db4dff30, message: 'Somerandomtextgoeshere2', posted: Wed Dec 31 2014 01:53:26 GMT+0100 (CET) }, { author: 54a34906af18e2a3db4dff2f, message: 'Somerandomtextgoeshere', posted: Wed Dec 31 2014 01:53:26 GMT+0100 (CET) } ] Maybe async issues?
I'd use a step debugger and see what's going on. Maybe users doesn't have what you think, or _id and author don't match, or something like that.
It finds matches, so it is working but it's like comment.username = user.username; doesn't write to the original comments object?
I added a console.log(comment.username); and it prints the correct username, but when I do console.log(comments); after the forEach loop it doesn't exist in there, it's the same as the unmodified one so the line comment.username = user.username does not write back to the original comments variable.
That doesn't make sense, The comment should be the exact same object as the one in the Array. Is there something more complicated going on that's not posted here, like some JSON parsing?
|
1

You can precache authors to avoid inner loop.

var cache = users.reduce(function(acc, user){
  acc[user._id] = user.name; 
  return acc;}, {}
);
comments.forEach(function(comment){
  comment.username = cache[comment.author];
});

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.