我有一个像这样的线程对象数组
threadlist:Thread[]= [thread{id:1},thread{id:2},thread{id:3},...]
如果用户有一个特定的书签线程,我也会在下面的用户对象中有一个ThreadRelation数组来存储。 请注意,Thread中的id与它在数组中的位置不匹配。
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
},..
]}
我想创建一个函数,该函数返回一个只包含用户书签线程的数组。我可以使用两个for循环和if语句实现这一点,但我不认为它有效.. 是否有一些方法可以直接在数组中找到该特定对象?
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])
}
}
}
}
}
谢谢!
答案 0 :(得分:1)
使用Array.prototype.filter
,您只能保留已添加书签的线程关系。从此筛选列表中,您可以基于id
条件构建线程列表。
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;
}));
}, []);
}
您还可以创建地图,以提高查找效果。
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]));
}, []);
}
答案 1 :(得分:1)
为什么不按照他们的ID保留“线程”的地图?
从数组创建地图:
var threadsById = new Map(threads.map(t => [t.id, t]));
获取是否存在threadid:
if (threadsById.has(threadRelation.id)) {
...
}
通过id获取线程:
var currentThread = threadsById.get(threadRelation.id);
答案 2 :(得分:1)
如果Thread.id
是唯一标识符,那么您真的应该使用Map
而不是没有键的Array
个对象。没有键,你将不得不迭代数组而没有其他选择。
在迭代Array
时,尝试使用内置的迭代方法,如forEach
。它们比循环更有效,看起来更整洁。
为了补充@Tamas-Hegedus's answer using ES6 iterator
feature,我使用当前版本的JavaScript创建了一个JSFiddle来制作“数组地图”,如果Map
不是Thread.id
,则可以将其替换为Web Api 2
数字。
请参阅JSFiddle。