Home > Net >  How can I filter an array containing varied object structures dynamically?
How can I filter an array containing varied object structures dynamically?

Time:09-09

My usage will contain 6 different object types (some which contain double nested arrays), and any possibility of number of entries, on the condition that an given entry is unique.

These objects do not have a consistent unique identifier (a unique identifier is applied in backend on submission).

here is an example of what the array may look like (only 2 object types):

arr = [
    {name:"aaa",time:15},
    {name:"aaa",time:22},
    
    {timeline: "250", chars[{a},{b},{c}]},
    {timeline: "220", chars[{d},{e},{f}]},
]
    
obj = {name:"aaa",time:22}

My intention is to gain a true or false based on if obj is inside arr

I have tried methods:

  1. I was suggested this method & it errors: #<Object> is not a function
console.log(arr.find(obj))
  1. I also found this suggestion but it will always return false even with the element present
console.log(arr.includes(object))
  1. I tried this method myself, though it will always fail.
console.log(arr.filter((element, index) => element === obj)

With attempt 4, If I was to compare name, this would be insufficient as unique time would be ignored missing valid entries.

If I was to pass every field, this would also not work as each object may or may not have the field and cause error.

Its not really possible to manually pre-filter filter into distinct categories, as every time a new type is added it will need manually adding to the filter.

If there is a library which could do this that you know of, please let me know as that would be perfect. Otherwise any other suggestions (excluding separating arrays) Would be greatly appreciated.

CodePudding user response:

I didn't put much thought on performace here but this might help:

function checkObjectInArray(arr, obj) {
  const res = arr.some((el) => deepEqual(el, obj));
  console.log(res);
}

function deepEqual(obj1, obj2) {
  if (Object.keys(obj1).length !== Object.keys(obj2).length) return false;
  for (let prop in obj1) {
    if (!obj2.hasOwnProperty(prop) || obj2[prop] !== obj1[prop]) {
      return false;
    }
  }
  return true;
}

in your case you can use it like:

arr = [
  { name: "aaa", time: 15 },
  { name: "aaa", time: 22 },

  { timeline: "250", data: ["2", "3", "4"] },
  { timeline: "251", data: ["2", "3", "4"] },  // what is chars[{d},{e},{f}] ?!
];

obj = { name: "aaa", time: 22 };

checkObjectInArray(arr, obj);

CodePudding user response:

Use arr.some() to check if the required object is present in the array.

To compare the objects, a simpler way is to Stringify both the Objects and compare them.

const arr = [
    {name:"aaa",time:15},
    {name:"aaa",time:22},
    {name: "aaa", chars: ["a", "b", "c"]},
    {name: "bbb", chars: ["d", "e", "f"]},
]

const obj1 = {name:"aaa", time: 15}
const obj2 = {name:"aaa",chars: ["a", "b", "c"]}

console.log(arr.some((element) => JSON.stringify(element) === JSON.stringify(obj1)))   // true
console.log(arr.some((element) => JSON.stringify(element) === JSON.stringify(obj2)))   // true

Didn't give much thought on performance.

  • Related