4

I have two arrays:

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

The contents of list is saved on a html file for efficiency (no need to re-render same data unless you refresh)

I want to remove a list item from the html if it doesn't exist anymore in the retrieved objects.

I know it is somewhere along the lines of the code below but I couldn't work it out.

//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
  }
}

Scenario:

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

Find that extra value in list and remove it.

List:

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

Object:

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

1: {
  //...
}
Abdul Sadik Yalcin
  • 1,744
  • 2
  • 19
  • 50

4 Answers4

4

You can to use filter and check if arrays match:

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);

In your case, to compare the objects inside the array, it's possible using Lodash, something like:

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>
BrTkCa
  • 4,703
  • 3
  • 24
  • 45
1

Also with find inside a filter :

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 ]
kevin ternet
  • 4,514
  • 2
  • 19
  • 27
1

First you have to somehow align the data. I suggest you get rid of the id="item-5756" for the items. Use data-id="5756" instead. After you have list of ids for local and remote, you can do what you suggested with the indexOf and just hide the local elements that are not in remote.

Check it out here: 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()
        }
    }
}

Note that there are several ways for improvement:

Better filtering algorithm: What I suggested has pretty bad efficiency. The ids can be sorted and filtered in one go. The lookup with [data="5678"] is rather slow as well.

Using data binding: Consider using angular or some other mvc framework to make your project maintainable. This way you can just keep track of one list of elements and let angular figure out the re-rendering.

Martin Gottweis
  • 2,721
  • 13
  • 27
0

if BaseArray is arr1 and receive from server is arr2, you must do a loop on arr1 and if not found in arr2 not push to 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);
    }
}

then arrOut is what you want.

hamid_reza hobab
  • 925
  • 9
  • 21