2

I have the following data structure that i receive from the api:

[
  {
    id: '10000844',
    text_id: '10000844-01',
  },
  {
    id: '10000844',
    text_id: '10000844-02',
  },
  {
    id: '12000844',
    text_id: '12000844-03',
  },
  {
    id: '12000844',
    text_id: '12000844-07',
  },
  {
    id: '12000814',
    text_id: '12000844-07',
  },
 {
    id: '12002812',
    text_id: '12000844-07',
  },
   {
    id: '12000814',
    text_id: '12000844-08',
  },
]

The perfect outcome of cleaning the code would be this result, basically returning only the first found id:

[
      {
        id: '10000844',
        text_id: '10000844-01',
      },
      {
        id: '12000844',
        text_id: '12000844-03',
      },
      {
        id: '12000814',
        text_id: '12000844-07',
      },
     {
        id: '12002812',
        text_id: '12000844-07',
      },
    ]

But currently it only returns the last found duplicate in a unique array, with the current code:

let uniqueArray = [...new Map(data.map(item =>
    [item.id, item])).values()];
2
  • stackoverflow.com/questions/2218999/… Commented Jun 29, 2022 at 6:39
  • I think you need to group and keep an array of text_ids Commented Jun 29, 2022 at 7:20

7 Answers 7

5

You can use Object.values() and reduce() same as :

const data = [
  {
    id: '10000844',
    text_id: '10000844-01',
  },
  {
    id: '10000844',
    text_id: '10000844-02',
  },
  {
    id: '12000844',
    text_id: '12000844-03',
  },
  {
    id: '12000844',
    text_id: '12000844-07',
  },
  {
    id: '12000814',
    text_id: '12000844-07',
  },
 {
    id: '12002812',
    text_id: '12000844-07',
  },
   {
    id: '12000814',
    text_id: '12000844-08',
  },
]

const result = Object.values(
  data.reduce((res, {id, text_id}) => {
    res[id] ??= {id, text_id}
    return res
  }, {})
)
console.log(result)

Update with ??= document

The logical nullish assignment (x ??= y) operator only assigns if x is nullish (null or undefined).

Sign up to request clarification or add additional context in comments.

4 Comments

You may want to explain what ??= does.
:) I know what it means but it's a relatively new feature so might be confusing. +1 for updating your answer.
I understood what you meant so I updated the answer
0

You can do it like this:

const arr = [
  {
    id: '10000844',
    text_id: '10000844-01',
  },
  {
    id: '10000844',
    text_id: '10000844-02',
  },
  {
    id: '12000844',
    text_id: '12000844-03',
  },
  {
    id: '12000844',
    text_id: '12000844-07',
  },
  {
    id: '12000814',
    text_id: '12000844-07',
  },
 {
    id: '12002812',
    text_id: '12000844-07',
  },
   {
    id: '12000814',
    text_id: '12000844-08',
  },
];
const unique = [];
const visited = new Set();
for(let i = 0; i < arr.length; ++i){
  if(!visited.has(arr[i].id)){
    unique.push(arr[i]);
    visited.add(arr[i].id);
  }
}

console.log(unique);

1 Comment

"You can do it like this" is not good documentation for an answer.
0

Concept

Loop through all the objects in the data and check if the id is found in result array. If not found then push it into the result array; otherwise, skip it.

Code

const data = [{
    id: '10000844',
    text_id: '10000844-01',
  },
  {
    id: '10000844',
    text_id: '10000844-02',
  },
  {
    id: '12000844',
    text_id: '12000844-03',
  },
  {
    id: '12000844',
    text_id: '12000844-07',
  },
  {
    id: '12000814',
    text_id: '12000844-07',
  },
  {
    id: '12002812',
    text_id: '12000844-07',
  },
  {
    id: '12000814',
    text_id: '12000844-08',
  },
];
let result = [];
let found;
data.forEach(d => {
  found = false;
  result.forEach(r => {
    if (!found && r.id === d.id) found = true;
  })
  if (!found) result.push(d);
});
console.log(result);

1 Comment

If the ids are not in order this will not work be careful!
0

Here is another way to achieve you desire output.
we use reduce for changing in data and use find function to get current id is already in prev or not if not then we use filter function to filter out same id object and push only first.

const data =[
  {
    id: '10000844',
    text_id: '10000844-01',
  },
  {
    id: '10000844',
    text_id: '10000844-02',
  },
  {
    id: '12000844',
    text_id: '12000844-03',
  },
  {
    id: '12000844',
    text_id: '12000844-07',
  },
  {
    id: '12000814',
    text_id: '12000844-07',
  },
 {
    id: '12002812',
    text_id: '12000844-07',
  },
   {
    id: '12000814',
    text_id: '12000844-08',
  },
]

const newData = data.reduce((prev, curr, index, arr) => {
  const find = prev.find(p => p.id === curr.id);
  if (!find) {
    const filter = arr.filter(f => f.id === curr.id);
    if (filter.length >= 1) {
      prev.push(filter[0])
    }
  }
  return prev;
}, [])

console.log(newData)

Comments

0

You can reduce the array into an object that stores only the first occurrence of every id and then extract the values from this object.

const 
  data = [{ id: "10000844", text_id: "10000844-01" }, { id: "10000844", text_id: "10000844-02" }, { id: "12000844", text_id: "12000844-03" }, { id: "12000844", text_id: "12000844-07" }, { id: "12000814", text_id: "12000844-07" }, { id: "12002812", text_id: "12000844-07" }, { id: "12000814", text_id: "12000844-08" }],
  result = Object.values(data.reduce((acc, d) => (!acc[d.id] ? { ...acc, [d.id]: d } : acc), {}));

console.log(result);

1 Comment

You may want to document how that one-liner works since it will be gibberish to beginners.
0

Some of the answers are already correct.

THIS ANSWER IS ONLY IF YOU ARE USING LODASH

You can use uniqBy.

This will return a duplicate-free version of an array where the first occurrence is the one that will be kept:

So in your case, something like

import uniqBy from 'lodash/uniqBy';

// dataFromAPI is your sample data
const unqiueArray = uniqBy(dataFromAPI, 'id');

Comments

0

Sometimes a simple loop is the way forward.

  1. Create a temporary object
  2. Iterate over the data adding objects to that object if their key can't be found.
  3. Get the values of the output object

const data=[{id:"10000844",text_id:"10000844-01"},{id:"10000844",text_id:"10000844-02"},{id:"12000844",text_id:"12000844-03"},{id:"12000844",text_id:"12000844-07"},{id:"12000814",text_id:"12000844-07"},{id:"12002812",text_id:"12000844-07"},{id:"12000814",text_id:"12000844-08"}];

// Initialise the output object
const out = {};

// Loop over the array of objects
for (const obj of data) {

  // For each object destructure the id from the rest
  // of its properties 
  const { id, ...rest } = obj;

  // If there is no property on the output
  // object with that key create it by adding
  // an object composed of the id and the other
  // object properties to it
  out[id] ??= { id, ...rest };
}

// Now return an array of
// the output object's values
console.log(Object.values(out));

Additional documentation

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.