0

So I have an array like this. Like array containing an array of objects.

posts = [
 [
 {
 "id": 2,
 "info": "This is some information"
 },
 {
 "id": 3,
 "info": "This is the other information"
 }
 ],
 [
 {
 "id": 2,
 "info": "This is a duplicated id I want to remove"
 },
 {
 "id": 4,
 "info": "This information is safe"
 }
 ]
]

I want to get the elements from each array and create a new array that only has the objects at the same time removing duplicated ids. What am trying to achieve is something like

posts = [
 {
 "id": 2,
 "info": "This is some information"
 },
 {
 "id": 3,
 "info": "This is the other information"
 },
 {
 "id": 4,
 "info": "This information is safe"
 }
]

This is the code I have so far

id = ids.map(val => {
 for(let i in val) {
 console.log(val)
 }
return something
})

I keep getting undefined values. I have tried forEach, for loop. Any help would be much appreciated. Thanks

asked Sep 26, 2022 at 19:24
0

5 Answers 5

1

Use flat to get a flattened array of objects, and then loop over the array. If the current object's id can't be found in an object in the output array push that object.

const posts=[[{id:2,info:"This is some information"},{id:3,info:"This is the other information"}],[{id:2,info:"This is a duplicated id I want to remove"},{id:4,info:"This information is safe"}]];
const out = [];
for (const obj of posts.flat()) {
 const found = out.find(f => obj.id === f.id);
 if (!found) out.push(obj);
}
console.log(out);

answered Sep 26, 2022 at 19:38

1 Comment

Thanks so much. I have no idea about flat. Now I know. Thanks
1

You could use .flat() and then .filter():

const posts = [
 [
 {
 id: 2,
 info: 'This is some information',
 },
 {
 id: 3,
 info: 'This is the other information',
 },
 ],
 [
 {
 id: 2,
 info: 'This is a duplicated id I want to remove',
 },
 {
 id: 4,
 info: 'This information is safe',
 },
 ],
];
const newPosts = posts.flat().filter((x, i, self) => i === self.findIndex((y) => x.id === y.id));
console.log(newPosts);

Another potential (and more optimal) solution could be this using .reduce():

const posts = [
 [
 {
 id: 2,
 info: 'This is some information',
 },
 {
 id: 3,
 info: 'This is the other information',
 },
 ],
 [
 {
 id: 2,
 info: 'This is a duplicated id I want to remove',
 },
 {
 id: 4,
 info: 'This information is safe',
 },
 ],
];
const newPosts = Object.values(posts.flat().reduce((acc, curr) => {
 return {
 ...acc,
 ...(!acc[curr.id] ? { [curr.id]: curr } : undefined),
 };
}, {}));
console.log(newPosts);

Or, if you don't like .reduce(), you can do something very similar with the Map object and a for...of loop:

const posts = [
 [
 {
 id: 2,
 info: 'This is some information',
 },
 {
 id: 3,
 info: 'This is the other information',
 },
 ],
 [
 {
 id: 2,
 info: 'This is a duplicated id I want to remove',
 },
 {
 id: 4,
 info: 'This information is safe',
 },
 ],
];
const map = new Map();
for (const item of posts.flat()) {
 if (map.has(item.id)) continue;
 map.set(item.id, item);
}
const newPosts = Array.from(map.values());
console.log(newPosts);

Or even use a classic for loop to get the job done:

const posts = [
 [
 {
 id: 2,
 info: 'This is some information',
 },
 {
 id: 3,
 info: 'This is the other information',
 },
 ],
 [
 {
 id: 2,
 info: 'This is a duplicated id I want to remove',
 },
 {
 id: 4,
 info: 'This information is safe',
 },
 ],
];
const flattened = posts.flat();
const map = {};
for (let i = 0; i < flattened.length; i++) {
 if (map[flattened[i].id]) continue;
 map[flattened[i].id] = flattened[i];
}
console.log(Object.values(map));

Either way, in each of these examples we're following the same workflow:

  1. Flatten the array so that all items are on the same level.
  2. Filter out the items with the duplicate IDs.
answered Sep 26, 2022 at 20:33

Comments

0

I group by id in order to remove duplicates.

var posts = [[{id:2,info:"This is some information"},{id:3,info:"This is the other information"}],[{id:2,info:"This is a duplicated id I want to remove"},{id:4,info:"This information is safe"}]];
var agg = {}
posts.forEach(function(arr) {
 arr.forEach(function(item) {
 agg[item.id] = agg[item.id] || item
 })
})
console.log(Object.values(agg))
.as-console-wrapper {
 max-height: 100% !important
}

answered Sep 26, 2022 at 19:29

2 Comments

the reduce could just be a forEach, also note that item.id will automatically be converted to string when it's used as an object key (no need for the ""+item.id
code cleaned, thanks.
0

Flatten the array with flat, then use a set to keep track of the ids we already have. The ternary inside the filter is logic to check if the id is already in the set, and if it is, we filter the item out. Otherwise, we add the id back to the set.

const posts = [[{id:2,info:"This is some information"},{id:3,info:"This is the other information"}],[{id:2,info:"This is a duplicated id I want to remove"},{id:4,info:"This information is safe"}]];
const flat = posts.flat();
const ids = new Set();
const filtered = flat.filter((item) => ids.has(item.id) ? false : ids.add(item.id));
console.log(filtered);
.as-console-wrapper {
 max-height: 100% !important
}

answered Sep 26, 2022 at 19:37

Comments

0

There are two things we need to do:

  • Flatten the inner areas into one main array with array.prototype.flat()
  • Remove duplicates based on, I'm assuming, the order of their appearance in the data.
    • We can do this by reducing the flattened array to an object with a condition that doesn't add any present id's if they're found
    • Then we convert that object to an array using Object.values()

let posts = [ [ { "id": 2, "info": "This is some information" }, { "id": 3, "info": "This is the other information" } ], [ { "id": 2, "info": "This is a duplicated id I want to remove" }, { "id": 4, "info": "This information is safe" } ] ]
let flattened = posts.flat()
console.log('Flattened: ', flattened)
let unique = flattened.reduce((acc, obj) => {
 if (!acc[obj.id]) {
 acc[obj.id] = obj
 }
 return acc
}, {})
console.log('Unique Objects: ', unique)
let result = Object.values(unique)
console.log('Final Array: ' ,result)

Doing it in one go and with a spread ... object merge:

let posts = [ [ { "id": 2, "info": "This is some information" }, { "id": 3, "info": "This is the other information" } ], [ { "id": 2, "info": "This is a duplicated id I want to remove" }, { "id": 4, "info": "This information is safe" } ] ]
let result = Object.values(
 posts.flat().reduce((acc, obj) => 
 ({...{[obj.id]: obj}, ...acc})
 , {})
);
console.log('Final Array: ', result);

answered Sep 26, 2022 at 19:40

Comments

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

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.