How to compare a part of an array item with a part of an array item from a second array?

Viewed 59

If I have two arrays with files

arr1 = ['file1.webp', 'file2.webp', ...];
arr2 = ['file1.jpg', 'file2.png', 'file3.jpg', 'file4.jpg', ...];

how would I check which array items are equal, minus the *.format part?

The idea is that, if there are two equal items, a webp and an alternative source are available. While if an item has no match, no webp source was provided. Both cases would lead to different image handling later on.

I could compare the items inside two arrays like so: let match = arr1.find( val => arr2.includes(val) );

But this compares each entire item. I only want to compare the file names. The formats in which the files were provided need to be cut off, so I get:

arr1 = ['file1', 'file2', ...];
arr2 = ['file1', 'file2', 'file3', 'file4', ...];

I can then filter out all matches between the two arrays. I've been searching for a solution for a real while, but I'm still not sure how to get there.

4 Answers

With a function that trims off the file extension, you can construct a Set of one of the transformed arrays. Then iterate over the other array and check whether its transformed item is in the Set or not:

const arr1 = ['file1.webp', 'file2.webp'];
const arr2 = ['file1.jpg', 'file2.png', 'file3.jpg', 'file4.jpg'];

const transform = str => str.replace(/\.[^.]+$/, '');
const set1 = new Set(arr1.map(transform));
for (const item of arr2) {
  if (set1.has(transform(item))) {
    console.log('Match for', item);
  } else {
    console.log('No match for', item);
  }
}

You can use filter() with nested some(). To get the file name from complete name use split('.')and get the first element using .split('.')[0]

let arr1 = ['file1.webp', 'file2.webp'];
let arr2 = ['file1.jpg', 'file2.png', 'file3.jpg', 'file4.jpg'];

let res = arr2.filter(a => arr1.some(b => a.split('.')[0] === b.split('.')[0]));
console.log(res)

You could filter by looking to the right side.

const getName = s => s.replace(/\.[^.]+$/, '');

var array1 = ['file1.webp', 'file2.webp'],
    array2 = ['file1.jpg', 'file2.png', 'file3.jpg', 'file4.jpg'],
    set1 = new Set(array1.map(getName)),
    common = array2.filter(s => set1.has(getName(s)));

console.log(common);

write extract method to get value to compare. Just use the extract method in your code. Alternatively, you can build an arr2Obj to not to repeat the searches.

const arr1 = ["file1.webp", "file2.webp"];
const arr2 = ["file1.jpg", "file2.png", "file3.jpg", "file4.jpg"];

const extract = item => item.split(".")[0];

let match = arr1.find(val => arr2.map(x => extract(x)).includes(extract(val)));

console.log(match);

// Alternatively, 
const arr2Obj = Object.assign({}, ...arr2.map(x => ({ [extract(x)]: 1 })));

const match2 = arr1.find(val => extract(val) in arr2Obj);

console.log(match2);

Related