-1

How can I check if a certain file name already exists in my array? For example, on initial load, I get some files from the server:

var initialFiles = ['file1_1','file2_0','file3_3','file4_2','file5_6'];

I push them to an array and set in sessionStorage:

filesArray.push(initialFiles);
sessionStorage.setItem('file-names', JSON.stringify(filesArray));

Then after a user interacts with the site, I get more files:

var newFiles = ['file1_1', 'file2_0', 'file1_2', 'file3_5', 'file4_6'];

You can see that file1_1 and file2_0 have already been loaded. How do I NOT add those file names in the array?

See an example here: http://jsbin.com/hiyefexudi/edit?html,js,console

kaoscify
  • 1,743
  • 7
  • 37
  • 74
  • `[].indexOf()`? https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/indexOf – biziclop Sep 16 '15 at 20:30

3 Answers3

1

You can check to see if each file in the new array is in the old one using indexOf == -1

fiddle: https://jsfiddle.net/L42h7uhm/

var initialFiles = ['file1_1', 'file2_0', 'file3_3', 'file4_2', 'file5_6'];

var newFiles = ['file1_1', 'file2_0', 'file1_2', 'file3_5', 'file4_6'];

newFiles.forEach(function (file) {
    console.log(initialFiles.indexOf(file) == -1);
});
Jesse
  • 1,262
  • 1
  • 9
  • 19
1

You can concatenate both arrays and filter out non-unique items.

var initialFiles = ['file1_1', 'file2_0', 'file3_3', 'file4_2', 'file5_6'];

var newFiles = ['file1_1', 'file2_0', 'file1_2', 'file3_5', 'file4_6'];

var newArray = initialFiles.concat(newFiles);

var uniqueArray = newArray.filter(function(item, pos) {
    return newArray.indexOf(item) == pos;
});

console.log(uniqueArray);
Matt O'Connell
  • 287
  • 3
  • 14
  • Thank you, I like this solution. – kaoscify Sep 16 '15 at 20:48
  • @mapr - This is not particularly efficient. Add all the duplicates (creating a new array while doing so), then create a new array by filtering that involves searching through the array for every item in the array, one at a time, even the items that were already dup-free. The `Set` object, either from ES6 or from a polyfill is the preferred design pattern for lists of items with no dups. – jfriend00 Sep 16 '15 at 21:04
  • @jfriend00 Not efficient due to speed? – kaoscify Sep 16 '15 at 21:10
  • @mapr - Yes, slower and inefficient from a memory usage and garbage collection point of view. But, with small numbers of items in the list, you probably wouldn't notice a performance difference. Mostly, it's just an inefficient design pattern to create two new arrays (one with `.concat()` and one with `.filter()` when all you want to do is add some non-dups to the original. The `Set` object is built exactly for that task, so I'm trying to teach a more appropriate design pattern for this type of problem. – jfriend00 Sep 16 '15 at 21:16
  • @jfriend00 Ok, that makes sense. Thanks so much for the detailed explanation. Extremely helpful. – kaoscify Sep 16 '15 at 21:19
0

Using ES6 semantics (modern browser, transpiled code or latest node.js), you can more efficiently use a Set object which will automatically keep duplicates out.

 var files = new Set(['file1_1','file2_0','file3_3','file4_2','file5_6']);
 var newFiles = ['file1_1', 'file2_0', 'file1_2', 'file3_5', 'file4_6'];
 files.add(...newFiles);

 sessionStorage.setItem('file-names', JSON.stringify(Array.from(files)));

Working demo: http://jsfiddle.net/jfriend00/7d1dy1p7/

MDN reference on the Set object


And, there are numerous polyfills for the Set object too as it is a generally useful concept, particularly for things like this. Here's one I've created: Mimicking sets in JavaScript?


Or, if you're trying to find out which items in the newFiles list are actually new and not in the files list already, then you can do that like this.

 var files = new Set(['file1_1','file2_0','file3_3','file4_2','file5_6']);
 var newFiles = ['file1_1', 'file2_0', 'file1_2', 'file3_5', 'file4_6'];

 var uniqueNewFiles = newFiles.filter(function(item) {
     return !files.has(item);
 });

Then, afterwards to update the existing files list, you can add these to it:

 files.add(...uniqueNewFiles);

Or, using a more capable Set object, you could do this:

 var files = new Set(['file1_1','file2_0','file3_3','file4_2','file5_6']);
 var newFiles = new Set(['file1_1', 'file2_0', 'file1_2', 'file3_5', 'file4_6']);

  var uniqueNewFiles = newFiles.difference(files);
Community
  • 1
  • 1
jfriend00
  • 683,504
  • 96
  • 985
  • 979
  • Hmm ok. How would this work if the `files` array kept on updating? So in this case you have 1 array that updates everytime, but I want to only store the new files in `sessionStorage`. – kaoscify Sep 16 '15 at 21:10
  • OK, I did not understand that was your question. A `Set` object is still useful for that. I've added a couple examples of using a `Set` object for that purpose. – jfriend00 Sep 16 '15 at 21:29
  • Ok thank you. I will test this out and let you know. – kaoscify Sep 16 '15 at 21:40