JavaScript - 如果一个值在另一个数组中不存在,如何从数组中删除它

4

我有两个数组:

//list elements from html
var list = document.querySelectorAll('#pres-list-ul li');
//list of retrieved objects from api
var objects = self.retrievedItems;

为了提高效率(无需重新渲染相同的数据,除非您刷新),列表内容保存在html文件中。

如果在检索到的对象中不存在一个列表项,则希望从html中删除它。

我知道以下代码大致上是这样的,但我无法解决它。

//I need to compare the id? For that another loop - which will run hundreds and thousands of time?
for(var j = 0; j < objects.length; j++) {
  if(objects.indexOf(list[i]) === -1) {
    //false
  } else {
    //true
  }
}

场景:

list:  57 //local
objects:  56 //online

找到列表中的额外值并将其删除。

列表:

<li id="item-5756" data-category="" data-group="" data-created="" data-author=""></li>

对象:

0: {
  id: //
  title: //
  description //
  // ...
}

1: {
  //...
}

你正在尝试找到两个列表的交集吗?每个列表中的项目是否唯一? - Joe
1
你能否发布listobjects的示例。 - Martin Gottweis
https://dev59.com/kXI-5IYBdhLWcg3wYnOQ - dstarh
@MartinGottweis 的示例已添加。 - Abdul Sadik Yalcin
@Devrim 已添加答案,请查看。 - Martin Gottweis
显示剩余2条评论
4个回答

4
你可以使用 filter 来检查数组是否匹配:

var array1 = [1,2,3,4,5,6,7,8,9],
    array2 = [1,2,3,4,5,6,7,8,9,10],
    result = [];

result = array2.filter(function(item){
  if ( array1.indexOf(item) !== -1 ) return item;
});

console.log(result);

对于您的情况,如果需要比较数组中的对象,可以使用Lodash进行操作,代码如下:

var array1 = [{'id': 1,'title': 'Test','description': 'Test'}, {'id': 2,'title': 'Test','description': 'Test'}, {'id': 3,'title': 'Test','description': 'Test'}],
    array2 = [{'id': 1,'title': 'Test','description': 'Test'}, {'id': 12,'title': 'Test','description': 'Test'}, {'id': 3,'title': 'Test','description': 'Test'}],
    result = [];

array2.forEach(function(item1){
  array1.forEach(item2 =>{     
    if ( _.isEqual(item1, item2) ){
      result.push(item2);  
    }
  });
});

console.log(result);
<script src="https://cdn.jsdelivr.net/lodash/4.16.4/lodash.min.js"></script>


1
同样在筛选器内使用find:

var list = [1,2,3,4,5,6,7,8,9];
var objects = [1,2,5,6,9,10,11,12,13,14];
var result = list.filter(item => objects.find(element => element === item));
console.log(result); //[ 1, 2, 5, 6, 9 ]

1
首先,您需要以某种方式对齐数据。我建议您删除项目的id="item-5756"。改用data-id="5756"。在获得本地和远程ID列表后,可以像您建议的那样使用indexOf来隐藏不在远程中的本地元素。

在此处查看:https://jsfiddle.net/jrwyopvs/

var remote_data = {
    5756: {
        id: 5756,
        title: '',
        description: '',
    },
    5757: {
        id: 5757,
        title: '',
        description: '',
    },
    5758: {
        id: 5758,
        title: '',
        description: '',
    },
}

$(document).on('click', '.filter', filter_local)

function filter_local () {
    var local_ids = $('#pres-list-ul li').toArray().map(function (element) { return $(element).data('id') })
    var remote_ids = []
    for (remote_index in remote_data) {
        remote_ids.push(remote_data[remote_index].id)
    }
    console.log(local_ids, remote_ids)

    for (local_id in local_ids) {
        if (remote_ids.indexOf(local_ids[local_id]) == -1) {
            $('#pres-list-ul li[data-id="' + local_ids[local_id] + '"]').hide()
        }
    }
}

请注意,有几种改进方式:
更好的过滤算法:我建议的效率非常低。可以一次性对id进行排序和过滤。使用[data="5678"]的查找也相当缓慢。
使用数据绑定:考虑使用angular或其他mvc框架使您的项目易于维护。这样,您只需跟踪一个元素列表,让angular解决重新渲染的问题。

谢谢Martin。我通过使用你的示例解决了它。我已经将两个数据存储在一个数组中,所以不需要重新映射它们 :) - Abdul Sadik Yalcin
1
很高兴能够帮助。祝你的项目好运。 - Martin Gottweis

0
如果BaseArray是arr1,从服务器接收到的是arr2,那么你必须在arr1上进行循环,如果在arr2中找不到,则不将其推送到arrOut。
var arr1=["abc","cde","efg","xyz"];
var arr2=["abc","cde","efg"];
var arrOut=[];
for(var i=0;i<arr1.length;i++){
    var out=arr2.find(function(element, index, array){return element===arr1[i];});
    if(out!=undefined){
        arrOut.push(out);
    }
}

那么arrOut就是你想要的。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接