陌陌如何做到变化的用户列表不会出现重复
发布于 9 年前 作者 crystaldust 5850 次浏览 最后一次编辑是 8 年前 来自 问答

以一个例子来描述问题: 在陌陌的用户列表中,是按照地理位置排序的,距离你最近的人会排在最上边。假设每一屏有5个人,刷第一屏的时候,按照距离排列的前10个用户为: A B C D E F G H I J

因为用户刷到的是第一屏,取前5个,也就是: A B C D E 当用户刷第二屏的时候,假设前十个人的排序发生了变化,变成: X Y Z A B C D E F G

那么第二屏的人就是: C D E F G

和第一屏的ABCDE的CDE就重复了,所以现在用户的屏幕上显示的10个人就是: ABCDECDEFG CDE各出现了2次

请问有没有行业里比较通用的一些解决方案?

22 回复

我觉得浏览过的可以用交集、差集处理掉,如果你认为使用者换了下一页就代表他不想深入了解第一页的内容(但是但他如果按了上一页又该怎么办呢)

@grass0916 也就是说,客户端拿到第二屏的资料后,和第一屏的数据做一个去重的操作吗?能具体说一下思路嘛?

@crystaldust 在你本次活跃(登录?或一次操作)时,保留一个回话信息跟你关联,在这里保存你附近的用户列表,所有交集并集操作都在这进行,第一页的剔除就是了

我有一个简单的想法: 用户第一次拉取“附近的人”第一屏的时候,记录用户当前位置, 拉取第二屏时,客户端请求里夹带之前的用户位置,以及已经被拉取过的“附近的人”。然后根据这两个信息再拉取10个人出来。 之后同上。

@funway 那意味着拉的屏越多,客户端请求的数据量越大

我觉得你想多了,思路就是传当前位置 + 页数 = 结果

@captainblue2013 嗯,也就是说,回话信息里保留一批和本用户相关的(按照距离计算),然后先从本地信息里进行操作,当超过回话信息用户数量时,再真正去服务器请求,是这样的思路吗?

@CarlosRen 主要是从用户体验上感觉很奇怪,会出现一个人反复在user list中出现的情况。我自己的程序信息变化更快,这一点比较明显,所以想找一个解决思路。

@chita 确实,除了数据量大,服务器查询的压力也会增加

@crystaldust 我觉得我说的很清楚,换种说法,你要做的很简单,更新数组,显示当前页 那么就这样实现就可以了啊 ABCDEFGHIJKLM 显示第2页 FGHIJ 更新 XYZABCDEFGH 显示第2页 CDEFG

或者你可以每次更新后就显示最近的,微博不就是么?显示最近更新的,刷完了写一下,更新了3个离你最近的人,不就ok了么

我怎么觉得是当拉完第一屏,记录下最远距离, 然后第二次请求加上第一次的最远距离,返回最远距离更远的人

@edward32tnt 嗯,以陌陌的业务逻辑应该是这样的。不过主要人和人之间的距离会发生变化,下一次去刷新的时候,有些人的距离已经更新了,有可能第一屏的人,恰好符合第二屏的距离,这样他就会出现在第二屏中。所以第一屏和第二屏有同一个人。

@CarlosRen 呃,大侠,我还是不太明白。我的问题在于,请求第一页的时候,排序是ABCDEFGHIJKLM,第一页取元素4,也就是ABCDE。第二页请求的时候,数据发生变化,按照排序是XYZABCDEFGH,第二页是要取元素5~9,也就是CDEFG。这时候客户端第一页有CDE,第二页也有CDE,不就重复了吗。是不是我表达的意思不太清楚?

@crystaldust 你更新了数组了啊亲。。。

var nearPeople= ["A","B","C","D","E","F","G","H","I","j","K"];
function ShowPeopleByPage(n){
	for(var i = (n-1)*5;i<n*5;i++){
		console.log("show"+nearPeople[i]);
	}
}
ShowPeopleByPage(2);
nearPeople.unshift("X");
nearPeople.unshift("Y");
nearPeople.unshift("Z");
console.log("===============after================")
ShowPeopleByPage(2);


=======================================================================
showF

index.html:5 showG index.html:5 showH index.html:5 showI index.html:5 showj index.html:12 ===============after================ index.html:5 showC index.html:5 showD index.html:5 showE index.html:5 showF index.html:5 showG 你要的是这种效果不?

@crystaldust 我觉得我现在这个代码就是你说的问题,其实很简单啊。。。你刷新之后从第一页开始显示即可啊。。。0 0 有啥纠结的

在取第2屏时 实际不是请求第2屏 而是取 offset > n 的 top 5 数据(按offset排序) n是上一屏最后一个的offset

这里要求offset 不能重复

具体还得看你用的GIS中间件

这种方式还有个小技巧就是 如果目标是显示5个 但是每次请求6个 返回6个表示还有下一页 不到6个表示到头了

@netwjx 嗯,对的,offset应该是客户端根据请求结果来设置的。哥哥,你和15楼的大哥头像太像了,看了半天我才分辨出来,哈哈

@crystaldust 引自樓主所述「主要是从用户体验上感觉很奇怪,会出现一个人反复在user list中出现的情况。」、「服务器查询的压力也会增加」。

我认为可以设定一个按钮可以重新刷屏,每次新的浏览都一次取得数个屏的试用者 list,如果触发上页下页都只是在前端中暂存的资料。还是楼主仍偏向每次点击页数都会刷新呢?

@grass0916 嗯,我有考虑过这种方案,在一定程度上可以缓解用户体验的问题。不过当用户用完暂存的资料后,还是需要去服务器请求,这个时候还是有可能出现重复的情况。

@crystaldust

var _ = require('underscore'); // http://underscorejs.org/#difference
var stack = [];

function getFiltered() {
	var now = _.difference(getList(), stack).slice(0, 5);
	stack = _.uniq(stack, now);

	return now;

	function getList() {
		// 第一次是 [A, B, C, D, E, F, G, H, I, J],
		// 第二次是 [X, Y, Z, A, B, C, D, E, F, G];
		return 某一 array;
	}
}

第一次 getFiltered() // Output : [A, B, C, D, E] 第二次 getFiltered() // Output : [X, Y, Z, F, G]

當對方重回首頁或刷新搜尋條件,才清除 stack。

這會是你要的嗎?

@grass0916 嗯,结果应该是这样的(去掉重复),只是这样的话,伺服器上就要针对每个user都缓存一个stack。如果用户一直asking more,恐怕要多一些消耗啦。

说实话,还是没太懂逻辑

回到顶部