4

I have an array of objects like this:

const result = [
  { ProductName: 'Orange', Origin: 'Italy' },
  { ProductName: 'Orange', Origin: 'Italy' },
  { ProductName: 'Lemon', Origin: 'Spain' },
  { ProductName: 'Avocado', Origin: 'Chile' }
];

// Expected output since there are duplicates:
const output = [{ ProductName: 'Orange', Origin: 'Italy' }]

Like shown above, there might be duplicates in the array (but it's not a must). That's why I'd like to:

  1. check if there are duplicates in the array
  2. if yes: create new array with only duplicates (show duplicate only 1x, even if there might be 2 or 3 duplicated in const result)
  3. if no: leave const result as is

By now, I tried to modify a code, which does the opposite: it finds unique (not duplicated) objects in the result-array. But I just can't get it work. Maybe it's just a wrong approach? Any help is appreciated!

const endresult = result
  .map(e => e.ProductName)
  .map((e, i, final) => final.indexOf(e) === i && i)
  .filter(e => result[e])
  .map(e => result[e]);
3
  • Loop over every element (you can ignore the last), and for every element check all elements that come after it (needs a second loop) if there's an object with the same product. If so, push that element into a new array (needs a check if there's already an object with the same product). At the end you have either an array of duplicated values, or an empty one because there are no dupes in the source.
    – Andreas
    Commented Dec 12, 2020 at 11:29
  • Please show your expected output. Do you expect out = [{ ProductName: 'Orange', Origin: 'Italy' }] or out = [{ ProductName: 'Orange', Origin: 'Italy' },{ ProductName: 'Lemon', Origin: 'Spain' },{ ProductName: 'Avocado', Origin: 'Chile' }]
    – pilchard
    Commented Dec 12, 2020 at 11:39
  • @pilchard: The expected output is: out = [{ ProductName: 'Orange', Origin: 'Italy' }]
    – Ewax_Du
    Commented Dec 12, 2020 at 11:42

5 Answers 5

1

Here is a solution using reduce:

const result = [
  {ProductName: "Orange", Origin: "Italy"},
  {ProductName: "Orange", Origin: "Italy"},
  {ProductName: "Lemon",  Origin: "Spain"},
  {ProductName: "Avocado",Origin: "Chile"},
  {ProductName: "Orange", Origin: "Italy"}
];

function getDuplicatesOrAll(arr) {
  const duplicates = arr
    .reduce((acc, p, i) => {
      const isDuplicate = i !== result.findIndex(({ProductName}) => ProductName === p.ProductName);
      if (isDuplicate) {
        const wasAlreadyMet = acc.some(({ProductName}) => ProductName === p.ProductName);
        if (!wasAlreadyMet) {
          acc.push(p);
        }
      }
      return acc;
    }, []);
    
  return duplicates.length ? duplicates : arr;
}

console.log( getDuplicatesOrAll(result) );

Maybe easier to read using your method to work with names only:

 const result = [
  {ProductName: "Orange", Origin: "Italy"},
  {ProductName: "Orange", Origin: "Italy"},
  {ProductName: "Lemon",  Origin: "Spain"},
  {ProductName: "Avocado",Origin: "Chile"},
  {ProductName: "Orange", Origin: "Italy"}
];

function getDuplicatesOrAll(arr) {
  const duplicates = arr
    .map(({ProductName}) => ProductName)
    .reduce((acc, name, i, final) => {
      const isDuplicate = i !== final.indexOf(name);
      if (isDuplicate) {
        const wasAlreadyMet = acc.includes(name);
        if (!wasAlreadyMet) {
          acc.push(name);
        }
      }
      return acc;
    }, [])
    .map(name => result.find(({ProductName}) => ProductName === name));

  return duplicates.length ? duplicates : arr;
}

console.log( getDuplicatesOrAll(result) );

3
  • Ok, so everything works when I have duplicates in the result-array. But when there are no duplicates I get an empty array. I suppose we need to include an additional if-else statement? What do you think?
    – Ewax_Du
    Commented Dec 12, 2020 at 11:59
  • @Ewax_Du I missed that part. I edited the code, and made a function to contain this logic
    – blex
    Commented Dec 12, 2020 at 12:07
  • Thanks. I tested the code and it works. I marked your answer as the solution because you gave me 2 possible code snippets and this made it easier for me - as a beginner - to follow. Thanks again!
    – Ewax_Du
    Commented Dec 12, 2020 at 13:39
1

Can be accomplished using Array#filter and Array#some.

  • Filter the array using Array#filter and for each object check if that object is repeated.
  • For a object its repetition can be checked using Array#some.
  • If duplicates are found return that, else return the original array

const result = [
  { ProductName: 'Orange', Origin: 'Italy' },
  { ProductName: 'Orange', Origin: 'Italy' },
  { ProductName: 'Orange', Origin: 'Italy' },
  { ProductName: 'Orange', Origin: 'Italy' },
  { ProductName: 'Lemon', Origin: 'Spain' },
  { ProductName: 'Avocado', Origin: 'Chile' },
];

const getDups = (arr) => {
  const seen = new Set
  const dups = arr
    .filter((o1, i)=> arr.slice(i+1)
                          .some(o2 => o1.ProductName === o2.ProductName &&
                                      o1.Origin === o2.Origin)           
                       &&      
                      !arr.slice(0, i)
                         .some(o2 => o1.ProductName === o2.ProductName &&
                                      o1.Origin === o2.Origin));
  if(dups.length){
    return dups;
  }
  return arr;
}

console.log(getDups(result));

1
  • 1
    @blex thanks for spotting that bug, fixed it now! Commented Dec 12, 2020 at 12:16
0

const result=[{ProductName:"Orange",Origin:"Italy"},{ProductName:"Orange",Origin:"Italy"},{ProductName:"Lemon",Origin:"Spain"},{ProductName:"Avocado",Origin:"Chile"}];

const findDuplicates = (arr)  => { 
    let result =[]
    arr.forEach((e,i) => {
        let slice = arr.slice(i+1)
        let dupl = slice.find(n => (n.ProductName === e.ProductName) && (n.Origin === e.Origin))
        if (dupl){
             if(!result.find(n => (n.ProductName === dupl.ProductName) && (n.Origin === dupl.Origin))){
            result.push(dupl)
            }
        }    
    })
    return result
}

console.log(findDuplicates(result))

0

You could do it using Array.prototype.sort() and Array.prototype.filter() method.

  • First, sort the array by ProductName.
  • Then use filter method for duplicates.
  • At last, if no duplicate is found then return the original array; otherwise, filtered duplicate result.

const result = [
  { ProductName: 'Orange', Origin: 'Italy' },
  { ProductName: 'Orange', Origin: 'Italy' },
  { ProductName: 'Lemon', Origin: 'Spain' },
  { ProductName: 'Avocado', Origin: 'Chile' },
];
let ret = result
  .sort((x, y) => x.ProductName.localeCompare(y.ProductName))
  .filter((x, i, a) => i > 0 && x.ProductName === a[i - 1].ProductName);
if (!ret.length) ret = result;
console.log(ret);

0

Make two object of unique items and duplicates, then check if duplicate exists make it array and return it.

const result = [
  { ProductName: 'Orange', Origin: 'Italy' },
  { ProductName: 'Orange', Origin: 'Italy' },
  { ProductName: 'Lemon', Origin: 'Spain' },
  { ProductName: 'Avocado', Origin: 'Chile' }
];

function duplicateFinder(array){
  const cache = {};
  const duplicates = {};
  let endResult = [];
  array.forEach(e=>{
    cache[e.Origin]?
      duplicates[e.Origin] = e:
      cache[e.Origin] = true;
  })
  Object.keys(duplicates).forEach(e => {
      endResult.push(duplicates[e])
  })
  return endResult.length ? endResult : array;
}

console.log(duplicateFinder(result))

0

Not the answer you're looking for? Browse other questions tagged or ask your own question.