2017-08-04 2 views
0

Je voudrais regrouper tous les messages entre 2 personnes dans un groupe (chat). Peu importe si je suis l'auteur ou le destinataire.Comment puis-je y parvenir avec Lodash?

Disons cet exemple de code.

const messages = [ 
    { id: '100', text: 'aaa', author: { id: '1' }, receiver: { id: '2' } }, 
    { id: '101', text: 'bbb', author: { id: '2' }, receiver: { id: '1' } }, 
    { id: '102', text: 'ccc', author: { id: '3' }, receiver: { id: '1' } }, 
] 

Imaginez, je suis utilisateur ID = 1, donc je voudrais obtenir ceci:

const chats = [ 
    { 
    chatName: 'Name of user ID 2', messages: [ 
     { id: '100', text: 'aaa', author: { id: '1' }, receiver: { id: '2' } }, 
     { id: '101', text: 'bbb', author: { id: '2' }, receiver: { id: '1' } }, 
    ] 
    }, 
    { 
    chatName: 'Name of user ID 3', messages: [ 
     { id: '102', text: 'ccc', author: { id: '3' }, receiver: { id: '1' } }, 
    ] 
    } 
]; 

Comment puis-je obtenir cela avec Lodash?

Répondre

1

ne suis pas sûr lodash, mais vous pouvez utiliser js plaine - reduce et map pour obtenir cette structure

const messages = [{ 
 
    id: '100', 
 
    text: 'aaa', 
 
    author: { 
 
     id: '1' 
 
    }, 
 
    receiver: { 
 
     id: '2' 
 
    } 
 
    }, 
 
    { 
 
    id: '101', 
 
    text: 'bbb', 
 
    author: { 
 
     id: '2' 
 
    }, 
 
    receiver: { 
 
     id: '1' 
 
    } 
 
    }, 
 
    { 
 
    id: '102', 
 
    text: 'ccc', 
 
    author: { 
 
     id: '3' 
 
    }, 
 
    receiver: { 
 
     id: '1' 
 
    } 
 
    }, 
 
]; 
 

 
function groupByPair(arr) { 
 
    return [ 
 
    ...arr.reduce((a, b) => { 
 
     let { 
 
     author, 
 
     receiver 
 
     } = b; 
 
     let s = [author.id, receiver.id].sort().join('-'); 
 
     a.set(s, a.has(s) ? a.get(s).concat(b) : [b]); 
 
     return a; 
 
    }, new Map) 
 
    ].map(e => ({ 
 
    chatName: 'Name of user ID ' + e[0].substring(e[0].indexOf('-') + 1), 
 
    messages: e[1] 
 
    })); 
 
} 
 
console.log(groupByPair(messages));

0

Vous pouvez le faire avec _.groupby. Je filtre le tableau d'abord pour que vous ne retrouvez avec des messages qui concernent l'utilisateur 1.

const messages = [ 
 
    { id: '100', text: 'aaa', author: { id: '1' }, receiver: { id: '2' } }, 
 
    { id: '101', text: 'bbb', author: { id: '2' }, receiver: { id: '1' } }, 
 
    { id: '102', text: 'ccc', author: { id: '3' }, receiver: { id: '1' } }, 
 
]; 
 

 
const filtered = messages.filter((msg) => { 
 
    return msg.author.id === '1' || msg.receiver.id === '1' 
 
}); 
 

 
const groups = _.groupBy(filtered, (msg) => { 
 
    return msg.author.id === '1' ? msg.receiver.id : msg.author.id 
 
}); 
 

 
console.log(groups);
<script src="https://unpkg.com/[email protected]"></script>

1

En utilisant soit Lodash ou Underscore.js:

var grouped = _.groupBy(messages, m => _.sortBy([m.author.id, m.receiver.id])); 
var formatted = _.map(grouped, (v, name) => ({ chatname: name, messages: v })); 

Vous pourrait les combiner en une seule ligne, mais cela semble trop dense à mes yeux.

Je pris la liberté de définir un ensemble de données de test plus complexe, pour vous assurer que les cas de pointe étaient mieux couverts:

var messages = [ 
    { id: '100', text: 'aaa', author: { id: '1' }, receiver: { id: '2' } }, 
    { id: '101', text: 'bbb', author: { id: '2' }, receiver: { id: '1' } }, 
    { id: '102', text: 'ccc', author: { id: '3' }, receiver: { id: '1' } }, 
    { id: '103', text: 'zzz', author: { id: '2' }, receiver: { id: '1' } }, 
    { id: '104', text: 'yyy', author: { id: '3' }, receiver: { id: '4' } }, 
    { id: '105', text: 'xxx', author: { id: '3' }, receiver: { id: '1' } } 

]

Avec ces données, le code ci-dessus donne une formatted de:

[ 
    { chatname: '1,2', 
    messages: [ 
     { id: '100', text: 'aaa', author: { id: '1' }, receiver: { id: '2' } }, 
     { id: '101', text: 'bbb', author: { id: '2' }, receiver: { id: '1' } }, 
     { id: '103', text: 'zzz', author: { id: '2' }, receiver: { id: '1' } } 
    ] 
    }, 
    { chatname: '1,3', messages: [ 
     { id: '102', text: 'ccc', author: { id: '3' }, receiver: { id: '1' } }, 
     { id: '105', text: 'xxx', author: { id: '3' }, receiver: { id: '1' } } 
    ] 
    }, 
    { chatname: '3,4', messages: [ 
     { id: '104', text: 'yyy', author: { id: '3' }, receiver: { id: '4' } } 
    ] 
    } 
] 

La principale différence avec votre sortie désirée concerne les valeurs chatname. Je n'ai pas vu comment vous étiez en train de les nommer, alors je suis resté avec les touches natives groupby de Lodash/Underscore.