Lodash:通过比较ID和其他属性来删除重复项

时间:2019-09-13 23:12:18

标签: javascript lodash

我在从Lodash中搜索方法时遇到了问题,并且尝试了uniqByuniqWith,但是都没有用,因为如果id中有相似之处,它将总是返回第一次出现的情况。由于现实中存在大量数据,因此不确定for循环选项是否足够好。

这是一个简单的版本:

var currentUserId = 1
var routes = [
    { id: 1, status: 0, memberId: 3},
    { id: 2, status: 1, memberId: 2},
    { id: 3, status: 1, memberId: null},
    { id: 2, status: 0, memberId: 1},
    { id: 4, status: 0, memberId: 1},
    { id: 5, status: 1, memberId: 2},
    { id: 5, status: 1, memberId: 1},
]

结果应优先考虑唯一ID。同时,它检查是否有1个以上的事件发生在相同的id和不同的memberId上。在这种情况下,它应该使用memberId === currentUserId来选择对象。

所以应该像这样:

var result = [
    { id: 1, status: 0, memberId: 3},
    { id: 2, status: 0, memberId: 1},
    { id: 3, status: 1, memberId: null},
    { id: 4, status: 0, memberId: 1},
    { id: 5, status: 1, memberId: 1},
]

2 个答案:

答案 0 :(得分:1)

无需使用loadash,只需使用过滤器

var currentUserId = 1
var routes = [
    { id: 1, status: 0, memberId: 3},
    { id: 2, status: 1, memberId: 2},
    { id: 3, status: 1, memberId: null},
    { id: 2, status: 0, memberId: 1},
    { id: 4, status: 0, memberId: 1},
    { id: 5, status: 1, memberId: 2},
    { id: 5, status: 1, memberId: 1},
];

const unique = (routes, userId) => routes.filter(
  (route, index) => !routes.some(
    (r, i) => r.id === route.id && index !== i && route.memberId !== userId
  )
);

console.log(unique(routes, currentUserId));

如果要按id订购,请添加.sort((a,b)=> a.id-b.id)

答案 1 :(得分:0)

另一种解决方案是先对数组进行排序,然后过滤出唯一的ID。

香草JS

  1. 在对原始数组进行排序时,请使用Array#slice来防止原始数组发生突变。

  2. 分别使用Array#sort

  3. 通过idmemberId对数组进行排序
  4. 使用Array#filter仅保留前一条路由与当前路由不同的id路由。


var result = routes
    .slice()
    .sort((a, b) => a.id - b.id || a.memberId - b.memberId)
    .filter((r, i, a) => !i || r.id - a[i-1].id);

const currentUserId = 1;
const routes = [
    { id: 1, status: 0, memberId: 3},
    { id: 2, status: 1, memberId: 2},
    { id: 3, status: 1, memberId: null},
    { id: 2, status: 0, memberId: 1},
    { id: 4, status: 0, memberId: 1},
    { id: 5, status: 1, memberId: 2},
    { id: 5, status: 1, memberId: 1},
];

var result = routes
	.slice()
	.sort((a, b) => a.id - b.id || a.memberId - b.memberId)
	.filter((r, i, a) => !i || r.id - a[i-1].id);

console.log(result);
.as-console-wrapper{min-height:100%;top:0!important;}

Lodash

  1. 使用lodash#sortBy分别对idmemberId进行排序。

  2. 使用lodash#uniqBy通过id获取唯一路线。

  3. 使用lodash#value获得最终结果。

  

如果您想知道链在lodash中的工作方式,可以访问implicit chainingexplicit chaining链接。


const result = _(routes)
  .sortBy(['id', 'memberId'])
  .uniqBy('id')
  .value();

const currentUserId = 1;
const routes = [
    { id: 1, status: 0, memberId: 3},
    { id: 2, status: 1, memberId: 2},
    { id: 3, status: 1, memberId: null},
    { id: 2, status: 0, memberId: 1},
    { id: 4, status: 0, memberId: 1},
    { id: 5, status: 1, memberId: 2},
    { id: 5, status: 1, memberId: 1},
];

const result = _(routes)
  .sortBy(['id', 'memberId'])
  .uniqBy('id')
  .value();
  
console.log(result);
.as-console-wrapper{min-height:100%;top:0!important}
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.min.js"></script>