1

I have the following JavaScript where I have some lists:

var deleteLinks = $(".remove-button .remove-from-cart");
deleteLinks.on('click', function(ev){
    ev.preventDefault();
    console.log("registered: " + deleteLinks);
    var currentHTML = $('.product');
    var currentText = $('.product .product-details .name-header');  
    var newHTML ;
        $.ajax({
        url: this.href,
        type: "GET",
        dataType: "html",
          success: function(data) {
              newHTML = $(data).find('.product .product-details .name-header'); 
              for(i = 0; i  < newHTML.length; i++){
                  console.log("new: " + newHTML[i].innerText);
                  console.log("old: " + currentText[i].innerText);
              }
          }
    });
});

The variable currentHTML contains an array of divs which are a container. The currentText contains an array of each container's name. The variable received in the AJAX response (newHTML) contains an array of names. This array is updated after some user interaction. One or more entries of the currentText variable may be missing and I want to find the indices of them so I can remove them from the container (currentHTML).

Can someone help me to find the indices of the missing elements between currentText and the retrieved data (newHTML)?

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
ItFreak
  • 2,299
  • 5
  • 21
  • 45
  • Possible duplicate of [Javascript algorithm to find elements in array that are not in another array](https://stackoverflow.com/questions/2963281/javascript-algorithm-to-find-elements-in-array-that-are-not-in-another-array) – Heretic Monkey Oct 02 '18 at 18:36
  • He wanted to compare two separate lists, then if those two had a match regardless of list 3. Check list 3 for the position of the item. – ABC Oct 02 '18 at 18:38

4 Answers4

2

To compare two array's value's there is many different approaches to simply see if a value is in another array. You might use array.indexOf(value) to return a position of an element in another array, if the result is greater than expected -1, it is present or the opposite missing. You might also use array.includes(value), and another way is to simply see if a value is not present by using !array.includes(value).

So knowing we can use !array.includes(value) to see if an array does not include a value. We must now loop through one array to grab entries and compare against another array for items that are not in the other array. We will use array.forEach() for this. We could possibly design more recursive functions using array.some(), but I am just trying to give you some simple examples.

Example 1.

// Data
let a = [1, 2, 3, 4, 5]; // Array A
let b = [1, 0, 9, 3, 5]; // Array B

// Basic principals
function check(a, b) {
    // Loop through A using array.some() => value
    a.forEach(value => {
        // B did not include value
        if (!b.includes(value)) {
            // Output
            console.log("B doesn't have", value, "at position", a.indexOf(value), "in A")
        }
    });
    // Loop through B using array.some() => value
    b.forEach(value => {
        // A did not include value
        if (!a.includes(value)) {
            // Output
            console.log("A doesn't have", value, "at position", b.indexOf(value), "in B")
        }
    });
}

// We are checking both Arrays A and B
check([1, 2, 3, 4, 5], [1, 0, 9, 3, 5]);

Example 2

Instead of just outputting to the console for demonstration purposes let's make a prototype for an array element, and then call a comparative function against array B. We will return an array with the [value, position] if that value is not in array B but indeed in array A.

// Data
let a = [1, 2, 3, 4, 5]; // Array A
let b = [1, 0, 9, 3, 5]; // Array B

/*
    Check an array for non-duplicates against another array.
    If the value of item in array A is present in array B,
    return [false, -1]. If value of item in array A is
    not present in B, return value and position of value
    in array A.
 */

Array.prototype.check = function(b) {
    /*
    * return if true
    *   [value, position]
    * else
    *   [false, -1]
    * */
    return a.map(v => {
       return (!b.includes(v) ? [v, a.indexOf(v)] : [false, -1])
    })
};

// Array A is checking against array B
console.log(a.check(b));

/*  Output:
    (A checking against B)
    [
      [ false, -1 ], // Array element 1 found in B
      [ 2, 1 ],  // Array element 2 not found in B, and has position 1 in A
      [ false, -1 ],  // Array element 3 found in B
      [ 4, 3 ], // Array element 4 not found in B, and has position 3 in A
      [ false, -1 ] // Array element 5 found in B
    ]
*/
ABC
  • 2,068
  • 1
  • 10
  • 21
  • I had such a solution too, but the 2 is contained in both arrays. I only want to find those indices that are in array 1, but not contained in array 2, for example: [1,2,3,4,5] and [2,1,5,4] should give a missing 3 and thus I want to get the index of 3 in the first array – ItFreak Oct 02 '18 at 18:27
  • Sorry, I was confused at first my bad. I fixed it, I got it right now 3rd edit lol. – ABC Oct 02 '18 at 18:49
1

If you have access to lodash, you can use _.difference to solve this in one line.

var a = ['a', 'b', 'c'],
  b = ['b'],
  result = [];
_.difference(a, b).forEach(function(t) {result.push(a.indexOf(t))});

console.log(result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.js"></script>
Rich
  • 1,567
  • 14
  • 24
  • Do you have a sample of multidimensional arrays? Let's say that every array object contains id and value properties. – Luciano Oct 28 '20 at 01:03
0

Assuming that you have unique elements in an array A and only one occurrence in the array B. We can just use set to add all the elements of array A and remove the elements from the set when you iterate over Array B. Use findIndex to look up for elements remaining in the set.

const a = [1,2,3,4,5];
const b = [2,1,5,4];
let set = new Set();
a.forEach(ele => set.add(ele));
b.forEach(ele => {
  if(set.has(ele)){
    set.remove(ele);
  }
});
let res = [];
for(let s of set) {
  if(a.findIndex(s) !== -1) {
    res.push({
     arr:  a,
     pos: a.findeIndex(s)
    });
  }else {
    res.push({
     arr:  b,
     pos: b.findeIndex(s)
    });
  }
}

The res array contains the index and the array in which the element is present.

0

As I can see from your code, you need to compare innerText of the two objects and find the indices of missing elemnts.

var missing_indices = [];
for(var i=0;i<currentText.length;i++){
    var found = false;
    for(var j=0;j<newHTML.length;j++){
        if(currentText[i].innerText == newHTML[j].innerText){
            found = true;
            break;
        }
    }
    if(!found){
        missing_indices.push(i);
    }
}

Then use missing_indices to remove missing elements from currentHTML

Eri.D
  • 1
  • 1