tesicg
tesicg

Reputation: 4053

How to filter the array using the content of another array?

The code looks as following:

inputArray = [
    { name: 'file1.jpg' },
    { name: 'file1.jpg' },
    { name: 'file2.jpg' },
    { name: 'file3.jpg' },
    { name: 'file4.jpg' }
]

filteringArray = ['file1', 'file2']

const outputArray = inputArray.filter( ? )

I need to filter the inputArrat so that the outputArray should contain only objects, which filenames ('name' property) are in filteringArray.

outputArray = [
    { name: 'file1.jpg' },
    { name: 'file2.jpg' }
]

I've worked so far with simpler filtering conditions, but I'm not sure how to solve this.

Upvotes: 0

Views: 63

Answers (3)

Jeya Suriya Muthumari
Jeya Suriya Muthumari

Reputation: 2021

You can use a simple function to do filter operation in the array using the filter logic array items as below.

var outputArray = [];
var inputArray = [
    { name: 'file1.jpg' },
    { name: 'file1.jpg' },
    { name: 'file2.jpg' },
    { name: 'file3.jpg' },
    { name: 'file4.jpg' }
];

var filteringArray = ['file1', 'file2'];

function filterItems(arr, query) {
  arr.filter(function(el) {
    query.forEach(function(item){
      if(el.name.toLowerCase().indexOf(item.toLowerCase()) !== -1){
        outputArray.push(el.name);
      }
    });      
  });
}

filterItems(inputArray, filteringArray);

console.log(remove_duplicates(outputArray));

function remove_duplicates(arr) {
    var obj = {};
    var ret_arr = [];
    for (var i = 0; i < arr.length; i++) {
        obj[arr[i]] = true;
    }
    for (var key in obj) {
        ret_arr.push(key);
    }
    return ret_arr;
}

NOTE: Updated the code, Now input array is having duplicate values. And in output array, there is no duplicate entry as I removed duplicates using a function (Remove duplicate values from JS array)

Upvotes: 1

Nick Parsons
Nick Parsons

Reputation: 50639

You can use .some() with .starsWith() to return true if the objects name starts with a file name present in your array like so:

const inputArray = [
    { name: 'file1.jpg' },
    { name: 'file2.jpg' },
    { name: 'file3.jpg' },
    { name: 'file4.jpg' }
];

const filteringArray = ['file1', 'file2'];
const outputArray = inputArray.filter(({name}) => filteringArray.some(file => name.startsWith(file)));

console.log(outputArray);

If you're looking for a solution which has a better time complexity (and has no duplicates), you could create a Map, which stores prefix file names as keys and the literal objects as values. Then, you can .map() your filteringArray using this map:

const inputArray = [
    { name: 'file1.jpg' },
    { name: 'file1.jpg' },
    { name: 'file2.jpg' },
    { name: 'file3.jpg' },
    { name: 'file4.jpg' }
]

const filteringArray = ['file1', 'file2'];
const lut = new Map(inputArray.map(({name}) => [name.split('.').shift(), {name}]));
const outputArray = filteringArray.map(f => lut.get(f));

console.log(outputArray);

Upvotes: 4

Avanthika
Avanthika

Reputation: 4182

You can use combination of filter and includes!

const inputArray = [
    { name: 'file1.jpg' },
    { name: 'file2.jpg' },
    { name: 'file3.jpg' },
    { name: 'file4.jpg' }
]

const filteringArray = ['file1', 'file2']

const outputArray = inputArray.filter((person) => filteringArray.includes(person.name.split(".")[0]))

console.log(outputArray);

Upvotes: 1

Related Questions