0

Okay, I have 2 arrays:

var state = {
  users: [
    {id: 1, name: 'Igor'},
    {id: 2, name: 'Anton'},
    {id: 3, name: 'Vasya'},
    {id: 4, name: 'Pete'},
    {id: 5, name: 'Dan'}
  ],

  chats: [
    {id: 1, users: [1,2], owner: 1},
    {id: 2, users: [1,2,3], owner: 2},
    {id: 3, users: [3,4,5], owner: 5}
  ]
}

I need a function that returns array like 'chats' but with actual names, not ids. So far I got this:

function loadChats() {
  return state.chats.map(item =>
      ({
        id: item.id,
        users: item.users.map(user => 
          state.users.find(usr => 
            usr.id === user).name),
        owner: item.owner       
      })
    )
}

But I donk think that solution is good, because we dont need to map all the array, just 'users' in it. So can anybody suggest better solution? I was thinking to do smth like this:

...  
state.chats.forEach(item =>
  item.users.map(user => 
    state.users.find(usr => 
      usr.id === user)
  )
)
...

But I don't like using forEach, is there any better solution?

5
  • Your state object in your example is wrong. users and chats should be assigned using : not =. Commented Dec 23, 2015 at 10:21
  • @AdamJeffers yeah I know, it was a typo. Fixed Commented Dec 23, 2015 at 10:22
  • @Tushar ids wont be numeral and in order, that is just example, they will be random 6-symbol combination Commented Dec 23, 2015 at 10:26
  • @ikffs Then you need an object having multiple elements inside it having key as id(unique` and value as username. Commented Dec 23, 2015 at 10:28
  • @Tushar yeah, I got it now Commented Dec 23, 2015 at 10:31

2 Answers 2

2

You're probably better off reducing the user array first and then directly referencing people by id, so you only loop over the users array once. It's no use to find the user in the array for every chat.

var users = state.users.reduce(function ( map, account ) {
        map[account.id] = account.name;
        return map;
    }, {}),
    conversations = state.chats.map(function ( chat ) {
        return {
            'id' : chat.id,
            'users' : chat.users.map(function ( id ) {
                return users[id];
            }),
            'owner' : users[chat.owner]
        };
    });
Sign up to request clarification or add additional context in comments.

2 Comments

problem is that ids won't be numeral and in order, it was for example, they will be 6 random symbols
Doesn't matter, you're reducing the names into an object, and objects can have any valid string as a key.
0

You're using arrow function so I guess you can use [].find():

var state = {
    users: [
        { id: 1, name: 'Igor' },
        { id: 2, name: 'Anton' },
        { id: 3, name: 'Vasya' },
        { id: 4, name: 'Pete' },
        { id: 5, name: 'Dan' }
    ],

    chats: [
        { id: 1, users: [1, 2], owner: 1 },
        { id: 2, users: [1, 2, 3], owner: 2 },
        { id: 3, users: [3, 4, 5], owner: 5 }
    ]
};

var users = state.users;
var chats = state.chats;

chats = chats.map(function each(chat) {
    // this replace the chat.users array and doesn't touch or hard code any other property
    chat.users = chat.users.map(function (id) {
        return users.find(function (user) {
            return user.id == id;
        }).name;
    });

    return chat;
});

console.log(chats);
document.write('<pre>' + JSON.stringify(chats, null, 3) + '</pre>');

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.