0

http://codepen.io/leongaban/pen/GZgrMK?editors=0010

I'm trying to find the most efficient way to accomplish this, in my actual app, I may have over 1000 items in the bigArray and a few hundred items or even all 1000 items again in the small array.

I need to find all those items and remove them. Lodash is faster than native javascript APIs so that's what I'm trying here:

var myApp = angular.module('myApp',[]);

myApp.controller('MyController', ['$scope', function($scope) {
  $scope.greeting = 'The array below should be smaller than bigArray';
  
  $scope.bigArray = [
    { name: 'Leon'},
    { name: 'Eric'},
    { name: 'Wes'},
    { name: 'Gannon'},
    { name: 'Jordan'},
    { name: 'Chris'},
    { name: 'Paulo'},
    { name: 'Gumbo'},
    { name: 'Gilgamesh'}
  ];

  $scope.smallArray = [
    { name: 'Gannon'},
    { name: 'Gumbo'},
    { name: 'Gilgamesh'}
  ]
  
  $scope.newArray = [];
  
  $scope.removeItems = function() {
    
      _.remove($scope.bigArray, function($scope.smallArray, n) {
          return $scope.smallArray[n].name;
      });

     // $scope.newArray = _.remove($scope.bigArray, function(n) {
     //   return n.name = _.find($scope.smallArray, 'name');
     // });

     // _.each($scope.bigArray, function(value, i) {
     //   _.find($scope.smallArray, 'name');
     // });
  }

}]);

What I've tried so far without luck.


Why am I asking about a lodash solution? Because the lodash API is faster in a lot of ways than the native Javascript API.

Proof lodash beats native Javascript, these results are from the jspref link Mr.zerkms posted: http://jsperf.com/zerkms-forloop-vs-each-from-lodash

enter image description here

enter image description here

Community
  • 1
  • 1
Leon Gaban
  • 36,509
  • 115
  • 332
  • 529
  • 1
    "Lodash is faster than native javascript APIs" --- that's because lodash is written in magical language by unicorns? – zerkms Feb 29 '16 at 21:43
  • Lodash isn't faster than native APIs. It's just a nice layer to polyfill when necessary and give you additional functions. [It frequently uses native APIs under the hood.](https://github.com/lodash/lodash/blob/master/lodash.js#L14985) – Mike Cluck Feb 29 '16 at 21:44
  • 1
    @zerkms You could have said that a little less pretentiously. Leon, zerkms means that Lodash can't be faster than JavaScript since it's built with JavaScript, but it may be better than methods you can write yourself. – Jack Guy Feb 29 '16 at 21:44
  • No because, a lot of their functions skip edge cases, and other optimizations... `_.each` is faster than both `forEach` and `for` for example because of that. – Leon Gaban Feb 29 '16 at 21:44
  • @LeonGaban [`each` uses a `while` loop.](https://github.com/lodash/lodash/blob/master/lodash.js#L477) A `for` loop is just syntactic sugar (with the possibility of providing *more* optimizations) over a `while` loop. See [here](http://stackoverflow.com/a/32381908/371184) for a fair comparison between lodash and a standard `for` loop. – Mike Cluck Feb 29 '16 at 21:46
  • As for your actual question, are the elements ordered in any way? – Mike Cluck Feb 29 '16 at 21:49
  • And now the answer: use the ES2015 `Set` data structure. – zerkms Feb 29 '16 at 21:50
  • LoDash can't be faster than native javascript, it's just not technically possible, and a library certainly isn't faster than a `for` loop written the correct way. As for the answer, just filter the big array based on wether or not the value exists in the small array, it's not that fast, but you'll never notice the difference – adeneo Feb 29 '16 at 21:51
  • Sigh, I've posted proof of this already with jspref, but I'll post it again soon. Others have commented on this as well here: http://stackoverflow.com/questions/18881487/why-is-lodash-each-faster-than-native-foreach – Leon Gaban Feb 29 '16 at 21:57
  • @LeonGaban That's true for `forEach` and *only* `forEach`. A standard `for` loop without a callback will always be faster. – Mike Cluck Feb 29 '16 at 22:00
  • But @LeonGaban you are being culled into believing that if it's done in lodash it has to be faster. Solution you chose can be witten to create object first and would be much faster regardless of using *"slower"* loops. Comparing an object property vs using `find()` within each iteration would be infinitely faster – charlietfl Feb 29 '16 at 22:04
  • Here I found my other post with the jspref stats, in my question I added `_.each` vs `for loop` http://stackoverflow.com/questions/35368609/how-to-compare-specific-items-in-array-inside-of-basic-lodash-loop I use `_.times` just to create the dummy Array to iterate over. (http://jsperf.com/forloop-vs-each-from-lodash) – Leon Gaban Feb 29 '16 at 22:06
  • 1
    @LeonGaban When I run it, the native is faster. This is especially true [when you cache the length of the array.](http://jsperf.com/forloop-vs-each-from-lodash/2) – Mike Cluck Feb 29 '16 at 22:12
  • 2
    @LeonGaban http://jsperf.com/zerkms-forloop-vs-each-from-lodash --- please stop posting benchmarks that make no sense – zerkms Feb 29 '16 at 22:13
  • 2
    Removing all the crap in that perf, and doing a proper comparison, would give you this -> http://jsperf.com/forloop-vs-each-from-lodash/6 – adeneo Feb 29 '16 at 22:16
  • @MikeC strange for me lodash still ran faster. And @ zerms, there is nothing wrong with my benchmark. Also the link you just posted, I ran it and lodash killed native. Posting a screen in my question. – Leon Gaban Feb 29 '16 at 22:17
  • @LeonGaban No need to be rude. Yes, your benchmark was messed up because you're adding in the variability of the `_.times` call as well as calls to `console.log`. Just waiting for access to the console can restrict performance. adeneo's is the most accurate. – Mike Cluck Feb 29 '16 at 22:18
  • @MikeC sorry, that was not aimed at you, and I feel that Mr Zerkms has been rude to me this entire time for some reason... but yes I went too far, cleaned up my comment. – Leon Gaban Feb 29 '16 at 22:22
  • 1
    @LeonGaban those images of perf test are completely irrelevant to the question. Please remember that question will live here for years – charlietfl Feb 29 '16 at 22:25
  • Possible duplicate of [javascript array difference](http://stackoverflow.com/questions/1187518/javascript-array-difference) – adeneo Feb 29 '16 at 22:29
  • @adeneo Not a duplicate, I'm asking how to accomplish this using Lodash. – Leon Gaban Feb 29 '16 at 22:29
  • 1
    And I'm telling you there are better and faster ways, using simple native methods, like [**this**](http://stackoverflow.com/questions/1187518/javascript-array-difference#answer-4026828) – adeneo Feb 29 '16 at 22:35
  • Possible duplicate of [using underscore's “difference” method on objects](http://stackoverflow.com/questions/13147278/using-underscores-difference-method-on-objects) – adeneo Feb 29 '16 at 22:47

2 Answers2

1

You're looking for _.filter instead of _.remove, I think

$scope.newArray = _.filter($scope.bigArray, function(item) {
   return !_.find($scope.smallArray, {name: item.name});
});
Jack Guy
  • 8,346
  • 8
  • 55
  • 86
1

it's just improvement on @Harangue answer

it will improve the performance when the second array is big

var smallObject = _.keyBy($scope.smallArray, 'name');
$scope.newArray = _.filter($scope.bigArray, function(item) {
   return !smallObject[item.name];
});

so instead of using 2 loops we can use 1 loop

Nour Sammour
  • 2,822
  • 1
  • 20
  • 19