I’m trying to filter out objects based on whether ALL the given search terms exist in SOME of the property values of EACH object in the array.
But I also don’t want to search within the deviceId
property.
But is there a way to do it with less code?
So I do the following:
- Convert the objects into iterable arrays
- Filter out the array to remove arrays with
deviceId
- Convert the arrays back into the Key/Value pair objects
let DeviceDtoArrayOfArray = []; DeviceDtos.forEach((indiv) => { DeviceDtoArrayOfArray.push(Object.entries(indiv)); }); let DeviceDtoArrayOfArrayFiltered = []; DeviceDtoArrayOfArray.forEach((indiv) => DeviceDtoArrayOfArrayFiltered.push( indiv.filter((indiv) => indiv[0] !== "deviceId") ) ); let DeviceDtoArrayOfArrayFilteredObjects = []; DeviceDtoArrayOfArrayFiltered.forEach((indiv) => { DeviceDtoArrayOfArrayFilteredObjects.push(Object.fromEntries(indiv)); });
- Define sample search term array
- For each object from Step 3, create an array of it’s property values
- Filter each Object in the array by searching each Search Term, check to see if it exists within some of the property values from Step 5, if it exists, then the object is returned to a new array, if not, it’s filtered out
Sample Array containing the objects with deviceId
const DeviceDtos = [ { deviceId: 1, deviceName: "Device0000", hwModelName: "Unassigned", deviceTypeName: "Unassigned", serviceTag: "A1A" },...
Sample Search Terms
const searchTerms = ["HwModel", "A1A"];
Filter out objects based on Search Terms
const results = DeviceDtoArrayOfArrayFilteredObjects.filter((indiv) => { const propertiesValues = Object.values(indiv); // all property values return searchTerms.every((term) => propertiesValues.some( (property) => property.toLowerCase().indexOf(term.toLowerCase()) > -1 ) ); }); console.log(results);
Advertisement
Answer
Map the array of devices to a new array, where one item is the device, and one is an array of strings composed from the keys and values (with the deviceId
excluded with rest syntax).
Then, all you have to do is filter that array by whether .every
one of the search terms is included in .some
of those strings.
const DeviceDtos = [ { deviceId: 1, deviceName: "Device0000", hwModelName: "Unassigned", deviceTypeName: "Unassigned", serviceTag: "A1A" }, { notincluded: 'notincluded' } ]; const devicesAndStrings = DeviceDtos.map( ({ deviceId, ...obj }) => [obj, Object.entries(obj).flat()] ); const searchTerms = ["hwModel", "A1A"]; const foundDevices = devicesAndStrings .filter(([, strings]) => searchTerms.every( term => strings.some( string => string.includes(term) ) )) .map(([obj]) => obj); console.log(foundDevices);