设计一个简化版的推特(Twitter),可以让用户实现发送推文,关注/取消关注其他用户,能够看见关注人(包括自己)的最近
10条推文。
- 用
map来存储每个user的tweets以及他关注的的follweeIds postTweet方法:如果当前userId已存在map中,往tweets里再次添加,如果不存在,则初始化当前user的tweets和followeeIds。这里需要存储当前用户的postTweet的时间createTime,js这里可以用perforance.now来记录,比Date.now的精度更高follow方法:如果当前被关注着不在关注列表follweeIds中,则添加,如果已经存在,不需要操作unfollow方法:如果在关注列表中,从列表中移除;不存在就不需要操作getNewsFeed方法: 从用户自己的tweets中和关注者的tweets获取最近(可以通过比较createTime确定)的十条tweets
class Twitter {
data: Map<
number,
{ tweets: { id: number; date: number }[]; followeeIds: number[] }
>
constructor() {
this.data = new Map()
}
postTweet(userId: number, tweetId: number): void {
if (this.data.has(userId)) {
this.data
.get(userId)!
.tweets.push({ id: tweetId, date: performance.now() })
} else {
this.data.set(userId, {
tweets: [{ id: tweetId, date: performance.now() }],
followeeIds: [],
})
}
}
getNewsFeed(userId: number): number[] {
if (!this.data.has(userId)) {
return []
}
let allMaybeTweets = this.data.get(userId).tweets
const followeeIds = this.data.get(userId).followeeIds || []
for (let i = 0; i < followeeIds.length; i++) {
const followeeId = followeeIds[i]
if (this.data.has(followeeId)) {
allMaybeTweets = allMaybeTweets.concat(this.data.get(followeeId).tweets)
}
}
return allMaybeTweets
.sort((a, b) => b.date - a.date)
.slice(0, 10)
.map((t) => t.id)
}
follow(followerId: number, followeeId: number): void {
if (this.data.has(followerId)) {
if (!this.data.get(followerId).followeeIds.includes(followeeId)) {
this.data.get(followerId).followeeIds.push(followeeId)
}
} else {
this.data.set(followerId, {
tweets: [],
followeeIds: [followeeId],
})
}
}
unfollow(followerId: number, followeeId: number): void {
if (
!this.data.has(followerId) ||
!this.data.get(followerId).followeeIds.includes(followeeId)
) {
return console.log('没有关注')
}
const oldUser = this.data.get(followerId)
this.data.set(followerId, {
tweets: oldUser.tweets,
followeeIds: oldUser.followeeIds.filter((f) => f !== followeeId),
})
}
}
这里可以优化的点:
- 因为
getNewsFeed只需要返回十条数据,所以可以每个用户的tweets中可以只保存最近的十条 - 这里直接使用了
sort排序,因为每个人的tweets的压入顺序是从近到远,可以用线性合并,即比较所有用户tweets列表第一个元素的createTime的方法获取最近的10条tweets。 - 这种从近到远的有时间顺序的
tweets可以用链表实现