LVC
LVC

Reputation: 125

How to filter array of objects with array of objects in javascript

I want to remove an object in an array if the object is not included from another array

i have an array of objects

let programs = [
            {"id":1,"name":"BSIT","description":"Bachelor of Science in Information Technology","institute":"IC"},
            {"id":2,"name":"BSIS","description":"Bachelor of Science in Information System","institute":"IC"},
            {"id":3,"name":"BSED","description":"Bachelor of Secondary Education","institute":"ITED"},
            {"id":4,"name":"BSAF","description":"BACHELOR OF SCIENCE IN AGRO-FORESTRY","institute":"IAAS"}
        ]

and i want to remove the objects that exist in this array of objects

let programs2 = [
            {"id":1,"name":"BSIT","description":"Bachelor of Science in Information Technology","institute":"IC"},
            {"id":2,"name":"BSIS","description":"Bachelor of Science in Information System","institute":"IC"},
            {"id":3,"name":"BSED","description":"Bachelor of Secondary Education","institute":"ITED"}
        ]

both are dynamic and they are fetched from database

i've tried filter but doesn't work.

here is my approach

const ress =ref(programs.filter(element => {
            if(programs2.includes(element.id))
            {
                return element
            }
        }))

i used axios to fetch data

Upvotes: 1

Views: 109

Answers (3)

Mr. Polywhirl
Mr. Polywhirl

Reputation: 48733

If you want to do a full equality check for each object, you can generate a hashcode for each object.

const main = () => {
  const filtered = subtract(data1, data2);
  console.log(filtered);
};

const subtract = (listA, listB) =>
  listA.filter((outer) =>
    !listB.some((inner) => areEqual(outer, inner)));

const areEqual = (a, b) => ObjectHash(a) === ObjectHash(b);

// Credit: https://stackoverflow.com/a/53905336/1762224
const ObjectHash = (() => {
  const hashFunc = (unkType, exclude) => {
    let ex = exclude;
    if (ex === undefined) ex = [];
    if (!isNaN(unkType) && typeof unkType !== 'string') return unkType;
    switch (typeof unkType) {
      case 'object': return objectHash(unkType, ex);
      default: return stringHash(String(unkType));
    }
  };
  const stringHash = (str, noType) => {
    let hashStr = str;
    if (!noType) hashStr = `string${str}`;
    let hash = 0;
    for (let i = 0; i < hashStr.length; i++) {
      hash = ((hash << 5) - hash) +  hashStr.charCodeAt(i);
      hash = hash & hash; // Convert to 32-bit int
    }
    return hash;
  };
  const objectHash = (obj, exclude) => {
    if (exclude.indexOf(obj) > -1) return undefined;
    let hash = '';
    const keys = Object.keys(obj).sort();
    for (let index = 0; index < keys.length; index += 1) {
      const key = keys[index];
      const keyHash = hashFunc(key);
      const attrHash = hashFunc(obj[key], exclude);
      exclude.push(obj[key]);
      hash += stringHash(`object${keyHash}${attrHash}`, true);
    }
    return stringHash(hash, true);
  };
  return hashFunc;
})();

const data1 = [
  {"id":1,"name":"BSIT","description":"Bachelor of Science in Information Technology","institute":"IC"},
  {"id":2,"name":"BSIS","description":"Bachelor of Science in Information System","institute":"IC"},
  {"id":3,"name":"BSED","description":"Bachelor of Secondary Education","institute":"ITED"},
  {"id":4,"name":"BSAF","description":"BACHELOR OF SCIENCE IN AGRO-FORESTRY","institute":"IAAS"}
]

const data2 =  [
  {"id":1,"name":"BSIT","description":"Bachelor of Science in Information Technology","institute":"IC"},
  {"id":2,"name":"BSIS","description":"Bachelor of Science in Information System","institute":"IC"},
  {"id":3,"name":"BSED","description":"Bachelor of Secondary Education","institute":"ITED"}
]

main();
.as-console-wrapper { top: 0; max-height: 100% !important; }

Upvotes: 0

elmaxe
elmaxe

Reputation: 21

Array.prototype.filter() should return a boolean (or something that can resolve to a truthy/falsy value)

let programs = [
            {"id":1,"name":"BSIT","description":"Bachelor of Science in Information Technology","institute":"IC"},
            {"id":2,"name":"BSIS","description":"Bachelor of Science in Information System","institute":"IC"},
            {"id":3,"name":"BSED","description":"Bachelor of Secondary Education","institute":"ITED"},
            {"id":4,"name":"BSAF","description":"BACHELOR OF SCIENCE IN AGRO-FORESTRY","institute":"IAAS"}
        ]

let programs2 = [
            {"id":1,"name":"BSIT","description":"Bachelor of Science in Information Technology","institute":"IC"},
            {"id":2,"name":"BSIS","description":"Bachelor of Science in Information System","institute":"IC"},
            {"id":3,"name":"BSED","description":"Bachelor of Secondary Education","institute":"ITED"}
        ]

let filtered = programs.filter(x => !programs2.find(y => y.id === x.id));

console.log(filtered) // [{"id":4,"name":"BSAF","description":"BACHELOR OF SCIENCE IN AGRO-FORESTRY","institute":"IAAS"}]

includes works only on arrays (and strings) and not on objects.

Upvotes: 2

R4ncid
R4ncid

Reputation: 7139

you can do something like this

const data1 = [
            {"id":1,"name":"BSIT","description":"Bachelor of Science in Information Technology","institute":"IC"},
            {"id":2,"name":"BSIS","description":"Bachelor of Science in Information System","institute":"IC"},
            {"id":3,"name":"BSED","description":"Bachelor of Secondary Education","institute":"ITED"},
            {"id":4,"name":"BSAF","description":"BACHELOR OF SCIENCE IN AGRO-FORESTRY","institute":"IAAS"}
        ]
        
const data2 =  [
            {"id":1,"name":"BSIT","description":"Bachelor of Science in Information Technology","institute":"IC"},
            {"id":2,"name":"BSIS","description":"Bachelor of Science in Information System","institute":"IC"},
            {"id":3,"name":"BSED","description":"Bachelor of Secondary Education","institute":"ITED"}
        ]
        
const filtered = data1.filter(({id}) => !data2.some(d => d.id === id))

console.log(filtered)

Upvotes: 4

Related Questions