2015-12-23 8 views
0

Хорошо, у меня есть 2 массивов:преобразовать массив объектами

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} 
    ] 
} 

Мне нужна функция, которая возвращает массив как «чаты», но с реальными именами, а не идентификаторами. До сих пор я получил это:

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  
     }) 
    ) 
} 

Но я донк думаю, что решение хорошо, потому что мы не должны отобразить весь массив, просто «пользователи» в нем. Так может ли кто-нибудь предложить лучшее решение? я думал сделать что-л так:

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

Но я не люблю использовать Foreach, есть ли лучшее решение?

+0

Ваше состояние объекта в вашем примере это неправильно. 'users' и' chats' должны быть назначены с помощью ':' not '='. – AdamJeffers

+0

@AdamJeffers Да, я знаю, это была опечатка. Исправлено. –

+0

. Истины @Tushar не будут численными и упорядоченными, это просто пример, они будут случайной комбинацией из 6 символов. –

ответ

2

Возможно, вам лучше сначала спустить массив пользователей, а затем напрямую ссылаться на людей по идентификатору, так что вы один раз перейдете через массив пользователей. Бесполезно находить пользователя в массиве для каждого чата.

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] 
     }; 
    }); 
+0

проблема в том, что идентификаторы не будут числиться и в порядке, например, они будут 6 случайными символами –

+1

Не имеет значения, вы уменьшаете имена в объект и объекты могут иметь любую действительную строку в качестве ключа. – Shilly

0

Вы используете функцию стрелки, так что я думаю, вы можете использовать [].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>');

Смежные вопросы