-1

Good day,

I have two arrays of strings. Strings are just numeric dates (eg: "01/01/2016"...).

I would like to know if there is a good/fast way to compare the two arrays and remove the strings from one array, which are not present in second one.

Example:

First array: ["01/01/2016","02/02/2015", "03/03/2014"]

Second array: ["01/01/2016", "02/02/2015"]

The string "03/03/2014" should be removed from the first array.

I have tried doing it though for() loops of both array lengths, but it seems to be very slow, because the arrays are big (abt. 1000+) indexes in each, like this:

  for (var a = 0; a < oilDateArray.length; a++) {
          for (var b = 0; b < fuelDateArray.length; b++) {
            if (fuelDateArray[b] !== oilDateArray[a]) {
              console.log("fuelDateArray not present: " + fuelDateArray[b]);
            }
          }
        }

Is there a specific function/method, which I could use in order to perform the above operation faster?

Thanks in advance and have a nice day!

Deniss M.
  • 3,617
  • 17
  • 52
  • 100
  • I don't think the answer provided there will be any faster. Checking two arrays which are 1000+ strings each by using for() loops is quite slow. – Deniss M. Jan 02 '16 at 19:29
  • Can you treat your dataset to use sorted UNIX timestamps instead? I can create an answer using time complexity `O(n)` if you can. – caulitomaz Jan 02 '16 at 19:36
  • I get this dates as data from a web service. I can convert it to unix or epoch time, but this would probably be a not very efficient way. – Deniss M. Jan 02 '16 at 19:37
  • It will be more efficient than using the `O(n²)` or `O(n*m)` algorithms that are popping here, considering converting to UNIX will take `O(n)` and sorting it will unnecessary. – caulitomaz Jan 02 '16 at 19:41
  • Thanks. I will try this way. – Deniss M. Jan 02 '16 at 19:44

4 Answers4

2

Try this :

for (var i = 0; i < firstArray.length; i++){
    if (secondArray.indexOf(firstArray[i]) == -1){ // indexOf is -1 if not found
        firstArray.splice(i, 1); // Remove 1 value at index i
        i--; // To re-adjust the index value which is 1 less because of the splice
    }
}

It may also be a bit slow, you can try with your array : https://jsfiddle.net/tyrsszaw/4

Cyxo
  • 506
  • 3
  • 11
  • You need to change `<=` to `<` and adjust `i` because you're reindexing the array when the item is removed. –  Jan 02 '16 at 19:45
  • You're right @squint , just a mistake – Cyxo Jan 02 '16 at 19:46
  • You still need to adjust `i`. Once you do the `.splice()`, the next index becomes the current one, so the `i++` skips over it. Under the `.splice()` line, add `i--`. –  Jan 02 '16 at 19:49
  • Oh ok I see what you mean – Cyxo Jan 02 '16 at 19:53
  • @squint this doesn't work. I get the length of the firstArray to be 0. This is the code I used: for (var g = 0; g < oilDateArray.length; g++){ if (fuelDateArray.indexOf(oilDateArray[g]) == -1){ // indexOf is -1 if not found oilDateArray.splice(g, 1); // Remove 1 value at index g g--; // To re-adjust the index value which is 1 less because of the splice //console.log("removed: " + oilDateArray[g]); } } – Deniss M. Jan 02 '16 at 20:18
  • @DenissM.: Works for me: https://jsfiddle.net/tar8v1p1/ –  Jan 02 '16 at 20:21
  • This works perfect! Thanks! – Deniss M. Jan 05 '16 at 19:49
1

with jquery

$(array1).filter(array2);

JAF
  • 350
  • 3
  • 19
  • This is just wrong. There's no documentation support for passing an array of strings to the `$` function and then using `.filter()` on it. –  Jan 02 '16 at 19:51
  • it's not, it works...I just tried it......Before giving me negs you should try the code for yourself – JAF Jan 03 '16 at 00:07
  • There's no documentation support for passing an array of strings to the `$` function and then using `.filter()` on it. Please read documentation before using (or suggesting) methods. It's really super, duper that it works right now, but it's an unsupported "feature" and can break on any minor point release. –  Jan 03 '16 at 00:31
  • ...and there's no indication that the OP is using jQuery in the first place, so it would be silly to load it just to do this simple little operation. –  Jan 03 '16 at 00:32
  • Ok, now I see where you go and you are right for long term purposes....I was just trying to help with a simple solution – JAF Jan 03 '16 at 00:33
1

If you have access to Set:

function intersect(arr1, arr2){
    var s = new Set(arr1);
    return arr2.filter(function(el){
        return s.has(el);
    });
}
MinusFour
  • 13,913
  • 3
  • 30
  • 39
0

i use jquery for array operations and i'll edit one for your need and paste here, i hope this can help you:

var arr1 = ["01/01/2016","02/02/2015", "03/03/2014"];
var arr2 = ["01/01/2016", "02/02/2015"];
var diff = [];

jQuery.grep(arr2, function(t) {
        if (jQuery.inArray(t, arr1) == -1) diff.push(t);
});

alert(diff);​ // what was different will be alerted 

i also found this code on stackoverflow sometime ago.

Update: Here is performance related topic you might be interested

Performance of jQuery.grep vs. Array.filter

tldr; it says grep is about 3 times faster. So stick with my solution. :)

Community
  • 1
  • 1
  • Thanks! How is it in terms of performance if comparing big arrays (1000+ items)? – Deniss M. Jan 02 '16 at 19:31
  • if you will work with anything related with javascript on client side, it depends on the client actually – Atilla Arda Açıkgöz Jan 02 '16 at 19:32
  • can you explain your case further? Like, if you need to fetch data from api or any connection to database? Or just some plain dates? – Atilla Arda Açıkgöz Jan 02 '16 at 19:36
  • I get these dates from a web service (xml) and then store them inside an array. – Deniss M. Jan 02 '16 at 19:38
  • i edited my answer about performance issue. – Atilla Arda Açıkgöz Jan 02 '16 at 19:40
  • Thanks! I'll check it out. Seems that jQuery is the solution. – Deniss M. Jan 02 '16 at 19:40
  • @DenissM.: Loading jQuery to do this operation is like using bazooka to kill a fly. –  Jan 02 '16 at 19:47
  • Seems, that there is no other solution, which is fast. – Deniss M. Jan 02 '16 at 19:53
  • @DenissM.: How could there be no other solution? jQuery is just a library of JS code, so if jQuery can do it, anyone can. In fact, you can get much faster than the provided solution. –  Jan 02 '16 at 19:55
  • @squint, can you please provide such a solution? I'm a bit new to JS. – Deniss M. Jan 02 '16 at 19:57
  • @DenissM.: paulolol's solution should be faster because it requires fewer function calls and uses all native code. You said you tried with `for` loops but it was too slow. If that was too slow, then there's something wrong because `for` loops are the fastest looping construct in JS. Also, MinusFour's solution is probably even faster. The trouble is that your question complains of a performance issue, but you provided no code, so how can anyone know if their solution will actually be better? –  Jan 02 '16 at 19:59
  • @squint you got a point. i never said that this is the absolute way he should use.Like i said that is what i've been using for my projects. Since he needs a fast working solution this code will fit his needs. – Atilla Arda Açıkgöz Jan 02 '16 at 20:02
  • @squint I have edited my question with the code I have used. This is not working at all now. – Deniss M. Jan 02 '16 at 20:03
  • @DenissM.: What isn't working? Your code or the solutions? –  Jan 02 '16 at 20:05
  • @squint my code. It is too slow. – Deniss M. Jan 02 '16 at 20:05
  • You don't have the `console.log()` actually in there, do you? –  Jan 02 '16 at 20:06
  • @squint I do for debugging. – Deniss M. Jan 02 '16 at 20:11
  • @DenissM.: Do you for performance testing? That will really slow things down if it gets called a lot. But put it this way, any solution that mimics what you're currently doing using things like `$.grep` or `.filter()` will be slower because it's the same basic algorithm but with the added overhead of function calls. –  Jan 02 '16 at 20:12
  • Also, what do you do when a match is found? Do you `break` the inner loop? Are you mutating the original array, or do you create a new array of unique items? There's still important info missing. –  Jan 02 '16 at 20:16
  • @squint for now I just console log the array element, that wasn't found in the second array. But after I will insert the one found into a new array. So a new array will be created with the correct found dates. – Deniss M. Jan 02 '16 at 20:19
  • @DenissM.: If doing you're `console.log()` on every pair that doesn't match, then *of course* it'll be slow. You're trying to optimize code that isn't even the actual application code yet. :P –  Jan 02 '16 at 20:25
  • But if you're going to `.push()` into a new array for matched items, the do the `.push()` and `break;` the inner loop. No sense continuing the inner loop when you've already found a match. –  Jan 02 '16 at 20:26
  • @squint ok thanks. I will try out. Thanks a lot for your time! – Deniss M. Jan 02 '16 at 20:32