0

I have these two array of objects and I want to get unique values from them! is anyone know how can I do that in JS?

let array1 = [
    { categoryName: "category 1" },
    { categoryName: "category 2" },
    { categoryName: "category 3" },
    { categoryName: "category 4" },
];

let array5 = [
    { categoryName: "category 1" },
    { categoryName: "category 2" },
    { categoryName: "category 3" },
    { categoryName: "category 4" },
    { categoryName: "category 5" },
];

let newArray = [];

for (const arr5Item of array5) {
  for (const arr1Item of array1) {
    if (arr5Item.categoryName !== arr1Item.categoryName) {
      newArray.push(arr5Item);
      break;
    } else {
      newArray.push(arr1Item);
      break;
    }
  }
}

console.log("newArray ", newArray);
Andy
  • 61,948
  • 13
  • 68
  • 95
Ali Mir
  • 126
  • 10
  • 2
    What have you tried so far? Did you try with methods like `.filter()`, `.find()`, etc? Unfortunately you can't just come here and ask people to write code for you. – Jeremy Thille Sep 30 '21 at 14:15
  • 4
    What is your required output? – Nitheesh Sep 30 '21 at 14:15
  • 1
    https://stackoverflow.com/questions/1187518/how-to-get-the-difference-between-two-arrays-in-javascript You can use this, and change the function so it will check the objects values – Reut Schremer Sep 30 '21 at 14:16
  • 1
    @ReutSchremer will check this. THanx – Ali Mir Sep 30 '21 at 14:18
  • @Nitheesh I just want a propper array either it is fully updated like the new value in it along with other values or only a single unique value – Ali Mir Sep 30 '21 at 14:19
  • @AliMir That other question will not work in your case. That answer only works for arrays containing strings and numbers. You need to compare objects. (In JavaScript, two objects are considered 'unique' even if they are identical in every way.) – Michael G Sep 30 '21 at 14:20
  • @MichaelG yes bro you are right!! but someone gave me the answer of reduce method seems to be working. – Ali Mir Sep 30 '21 at 14:23
  • 2
    Please add your expected output for the given input to make the question more clear. – Nitheesh Sep 30 '21 at 14:32

5 Answers5

1

Array.reduce can solve your problem easily.

Step 1: Merge all of your array into one array, by three dots in javascript.

Step 2: Use Array.reduce to return your result.

let array1 = [
    { categoryName: "category 1" },
    { categoryName: "category 2" },
    { categoryName: "category 3" },
    { categoryName: "category 4" },
];

let array5 = [
    { categoryName: "category 1" },
    { categoryName: "category 2" },
    { categoryName: "category 3" },
    { categoryName: "category 4" },
    { categoryName: "category 5" },
];

const mergedArray = [...array1, ...array5];

const uniqueArray = mergedArray.reduce((acc, item) => {
   if (!acc.some(e => e.categoryName == item.categoryName)) {
      acc.push(item);
   }
   return acc;
}, []);
console.log(uniqueArray);
Tuan Dao
  • 2,647
  • 1
  • 10
  • 20
  • Thanx man this solution worked for me. basically, I wanted to retain the other values in the array except for the categorName and this function does exactly the same. thanx so much. – Ali Mir Sep 30 '21 at 17:09
1

You can easily achieve the result using Set. Using Set is efficient way

1)

let array1 = [
  { categoryName: "category 1" },
  { categoryName: "category 2" },
  { categoryName: "category 3" },
  { categoryName: "category 4" },
];

let array5 = [
  { categoryName: "category 1" },
  { categoryName: "category 2" },
  { categoryName: "category 3" },
  { categoryName: "category 4" },
  { categoryName: "category 5" },
];

const set = new Set([
  ...array1.map((o) => o.categoryName),
  ...array5.map((o) => o.categoryName),
]);

const result = [...set.keys()].map((s) => ({ categoryName: s }));
console.log(result);

2)

let array1 = [
  { categoryName: "category 1" },
  { categoryName: "category 2" },
  { categoryName: "category 3" },
  { categoryName: "category 4" },
];

let array5 = [
  { categoryName: "category 1" },
  { categoryName: "category 2" },
  { categoryName: "category 3" },
  { categoryName: "category 4" },
  { categoryName: "category 5" },
];

const set = new Set([
  ...array1.map((o) => o.categoryName),
  ...array5.map((o) => o.categoryName),
]);

const result = [];

for (let categoryName of set) result.push({ categoryName });
console.log(result);
DecPK
  • 24,537
  • 6
  • 26
  • 42
1

Not just one. There are a lot of methods available for this. Basically you need a looping logic.

Please find the Array.reduce implementation.

Logic

  • Create a merged array, by using spread operator.
  • Check each node of merged array in accumulator.
  • If the node from the merged array, doesnot exist in accumulator, then its unique.

Working Fiddle

let array1 = [{ categoryName: "category 1" },{ categoryName: "category 2" },{ categoryName: "category 3" },{ categoryName: "category 4" }];
let array5 = [{ categoryName: "category 1" },{ categoryName: "category 2" },{ categoryName: "category 3" },{ categoryName: "category 4" },{ categoryName: "category 5" }];
const uniqueValues = [...array1, ...array5].reduce((acc, curr) => {
  const nodeExist = acc.some(item => item.categoryName === curr.categoryName);
  const secondArrayExist = array5.some(item => item.categoryName === curr.categoryName);
  if (!nodeExist) {
    acc.push(curr);
  }
  return acc;
}, []);
console.log(uniqueValues);

If you want to get the nodes which are present in only in any one of the array, use the below logic.

Logic

  • Create a merged array.
  • Check each node in the merged array, whether its present in array1 and array5. If the node is not present in any one of array1 or array5 then this is unique node.
  • Push that node to accumulator.

Working Fiddle

let array1 = [{ categoryName: "category 1" },{ categoryName: "category 2" },{ categoryName: "category 3" },{ categoryName: "category 4" }];
let array5 = [{ categoryName: "category 1" },{ categoryName: "category 2" },{ categoryName: "category 3" },{ categoryName: "category 4" },{ categoryName: "category 5" }];
const uniqueValues = [...array1, ...array5].reduce((acc, curr) => {
  const firstArrayExist = array1.some(item => item.categoryName === curr.categoryName);
  const secondArrayExist = array5.some(item => item.categoryName === curr.categoryName);
  if (!firstArrayExist || !secondArrayExist) {
    acc.push(curr);
  }
  return acc;
}, []);
console.log(uniqueValues);
Nitheesh
  • 19,238
  • 3
  • 22
  • 49
1

By using Set (for unique object) and JSON.stringify and JSON.parse. Assuming along with categoryName you may have other properties in the object.

let array1=[{categoryName:"category 1"},{categoryName:"category 2"},{categoryName:"category 3"},{categoryName:"category 4"},]

let array5=[{categoryName:"category 1"},{categoryName:"category 2"},{categoryName:"category 3"},{categoryName:"category 4"},{categoryName:"category 5"},];

const combineArr = [...array1.map(x=> JSON.stringify(x)), ...array5.map(x=> JSON.stringify(x))];

const result = [...new Set(combineArr)].map(x => JSON.parse(x));

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0 }
navnath
  • 3,548
  • 1
  • 11
  • 19
1

Here is a little bit extended snippet, which basically introduce function for merging any number of arrays and filter them by provided prop key to leave only unique values. Check inline comments

// Arrays
let array1 = [
    { categoryName: "category 1" },
    { categoryName: "category 2" },
    { categoryName: "category 3" },
    { categoryName: "category 7" } // unique
];
let array3 = [
    { categoryName: "category 1" },
    { categoryName: "category 2" },
    { categoryName: "category 6" }, // unique
    { categoryName: "category 3" },
    { categoryName: "category 4" }
];
let array5 = [
    { categoryName: "category 1" },
    { categoryName: "category 5" }, // unique
    { categoryName: "category 2" },
    { categoryName: "category 3" },
    { categoryName: "category 4" }
];

// Merge diff
const md = (arr, key) => {
  const merged = [];
  // Merge all
  for(const el of arr) merged.push(...el);
  // Find duplicates
  const matched = {};
  const dup = {};
  const res = merged.filter(el => matched.hasOwnProperty(el[key]) ? (() => { dup[el[key]] = true; return false })() : (matched[el[key]] = true));
  // Filter out matched duplicates and return
  return merged.filter(el => dup.hasOwnProperty(el[key]) ? false : true);
}

// Test
// Give array of arrays as first parameter
// and prop name to match and filter as second
console.log(md([array1, array3, array5], "categoryName"));
tarkh
  • 2,424
  • 1
  • 9
  • 12