skip to Main Content

I have an object array and I want to filter it so that it only contains duplicates (by duplicates I mean objects that have the same value for the key number) and remove objects that have a unique number value. I want to keep all duplicate objects (not just identify what the duplicate values are!). The duplicates will always be in consecutive order.

My array:

const array = [
  {
   number: 1,
   color: "red"
  },
  {
   number: 2,
   color: "blue"
  },
  {
   number: 2,
   color: "yellow"
  },
  {
   number: 3,
   color: "black"
  },
  {
   number: 3,
   color: "orange"
  },
  {
   number: 4,
   color : "white"
  }
]

Expected output :

[
  {
   number: 2,
   color: "blue"
  },
  {
   number: 2,
   color: "yellow"
  },
  {
   number: 3,
   color: "black"
  },
  {
   number: 3,
   color: "orange"
  }
]

I have searched high and low but all answers seem to either remove or identify duplicates and since I’m new to javascript I don’t have the skills to modify those codes to work for me. Any help is greatly appreciated!

2

Answers


  1. A straightforward approach is to filter the array and retain all elements for which you can find some element with the same number at a different position in the array:

    const result = array.filter(
      (v1, i1, a) => a.some((v2, i2) => v1.number === v2.number && i1 !== i2)
    );
    

    Complete snippet:

    const array = [
      {
       number: 1,
       color: "red"
      },
      {
       number: 2,
       color: "blue"
      },
      {
       number: 2,
       color: "yellow"
      },
      {
       number: 3,
       color: "black"
      },
      {
       number: 3,
       color: "orange"
      },
      {
       number: 4,
       color : "white"
      }
    ];
    
    const result = array.filter(
      (v1, i1, a) => a.some((v2, i2) => v1.number === v2.number && i1 !== i2)
    );
    
    console.log(result);
    Login or Signup to reply.
  2. Using a solution like the other answer will cost more iteration cycles for every element as the current index increases.

    You can filter the array in two cycles total by memoizing the counts in the first iteration cycle.

    For small arrays like the one in your question this won’t matter, but for very large arrays the optimization will become noticeable.

    Code in TS Playground

    type NumberKey = { number: number };
    
    function getCounts<T extends NumberKey>(array: T[]): Map<number, number> {
      const counts = new Map<number, number>();
      for (const { number } of array) counts.set(number, (counts.get(number) ?? 0) + 1);
      return counts;
    }
    
    function filterDupes<T extends NumberKey>(array: T[]): T[] {
      const counts = getCounts(array);
      return array.filter(({ number }) => (counts.get(number) ?? 0) > 1);
    }
    
    const array = [
      { number: 1, color: "red" },
      { number: 2, color: "blue" },
      { number: 2, color: "yellow" },
      { number: 3, color: "black" },
      { number: 3, color: "orange" },
      { number: 4, color: "white" },
    ] satisfies (Record<PropertyKey, unknown> & NumberKey)[];
    
    const dupes = filterDupes(array);
    console.log(dupes); // [{ number: 2, color: "blue" }, { number: 2, color: "yellow" }, { number: 3, color: "black" }, { number: 3, color: "orange" }]
    
    

    Compiled JS from the playground link:

    "use strict";
    function getCounts(array) {
        const counts = new Map();
        for (const { number } of array)
            counts.set(number, (counts.get(number) ?? 0) + 1);
        return counts;
    }
    function filterDupes(array) {
        const counts = getCounts(array);
        return array.filter(({ number }) => (counts.get(number) ?? 0) > 1);
    }
    const array = [
        { number: 1, color: "red" },
        { number: 2, color: "blue" },
        { number: 2, color: "yellow" },
        { number: 3, color: "black" },
        { number: 3, color: "orange" },
        { number: 4, color: "white" },
    ];
    const dupes = filterDupes(array);
    console.log(dupes);
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search