This question already has answers here:
Get all unique values in a JavaScript array (remove duplicates)
(91 answers)
How to remove all duplicates from an array of objects?
(77 answers)
Remove duplicate values from an array of objects in javascript [duplicate]
(6 answers)
Closed 3 years ago.
Duplicate values are being storing into an array of object
Based on the given userID need to out the duplicate userId,
if it exist do nothing, else push that userIdinto the teamSocketsList array
But with the below piece of code duplicate values are being stored into an array teamSocketsList
var TeamUser = {
userId : userID,
socketId : socket.id
}
var i = $.inArray( userID, teamSocketsList );
if(i == -1){
teamSocketsList.push(TeamUser);
}else{
teamSocketsList = jQuery.grep(teamSocketsList, function(value) {
return value != userID;
});
}
Actual Result:
[
{"userId":1,"socketId":"M8xzpi3O0cMHXe-dAAAK"},
{"userId":1,"socketId":"ZIbgYMLOda_R5QqvAAAN"},
{"userId":9,"socketId":"XAf1cepsLv-KDpn3AAAQ"},
{"userId":9,"socketId":"XAf1cepsLv-KDpn3AAAQ"}
]
Expected Result:
[
{"userId":1,"socketId":"M8xzpi3O0cMHXe-dAAAK"},
{"userId":9,"socketId":"XAf1cepsLv-KDpn3AAAQ"},
]
Edit:
Here I'm expecting userID to be pushed in to an array teamSocketsList based on the condition, if at all the given userID matches in the present list should return false or do nothing. Otherwise, (iff, it's not at all included then) store it into an array with the auto-generated socketId value
The logic which I had tried to implement was to check whether if that array is empty or not and then, traverse all the elements in the array list so that whenever userID were given as an input it must check the condition and then push that element.
Based on the present answers put up, it'll store the duplicate values and then sort it on and assign it back to teamSocketsList, that's fine.
Along with already mentioned values/reduce, you can take advantage of Set():
const myArray = [
{"userId":1,"socketId":"M8xzpi3O0cMHXe-dAAAK"},
{"userId":1,"socketId":"ZIbgYMLOda_R5QqvAAAN"},
{"userId":9,"socketId":"XAf1cepsLv-KDpn3AAAQ"},
{"userId":9,"socketId":"XAf1cepsLv-KDpn3AAAQ"}
]
const unique = (arr, key) => {
const keys = new Set();
return arr.filter(el => !keys.has(el[key]) && keys.add(el[key]));
};
console.log(unique(myArray, "userId"));
In opposition to other response I can point out that with this method is easier to change array and key without adding code.
use reduce along with Object.values. create an object whose keys are userId. If the key does not exist, create the key and then use Object.values to get the required ouput.
const input = [
{"userId":1,"socketId":"M8xzpi3O0cMHXe-dAAAK"},
{"userId":1,"socketId":"ZIbgYMLOda_R5QqvAAAN"},
{"userId":9,"socketId":"XAf1cepsLv-KDpn3AAAQ"},
{"userId":9,"socketId":"XAf1cepsLv-KDpn3AAAQ"}
];
const output = Object.values(input.reduce((accu, {userId, socketId}) => {
if(!accu[userId]) accu[userId] = {userId, socketId};
return accu;
}, {}));
console.log(output);
How about this function where you pass in your array and the key to get your result
const convertArrayToObjecByID = ({ array, key }) =>
array.reduce((obj, item) => {
return { ...obj, [item[key]]: item };
}, {})
const input = [
{"userId":1,"socketId":"M8xzpi3O0cMHXe-dAAAK"},
{"userId":1,"socketId":"ZIbgYMLOda_R5QqvAAAN"},
{"userId":9,"socketId":"XAf1cepsLv-KDpn3AAAQ"},
{"userId":9,"socketId":"XAf1cepsLv-KDpn3AAAQ"}
]
const myObject = convertArrayToObjecByID({ array:input, key:'userId' })
console.log({myObject})
//then if you want it as an array
console.log(Object.keys(myObject).map(item => myObject[item]))
You can store your data in the object (key-value pair) and avoid adding duplicate data.
For example:
var teamSocketsList = {};
var TeamUser = {
userId : userID,
socketId : socket.id
}
teamSocketsList[TeamUser.userId] = TeamUser;
Then if you are adding new user to teamSocketsList, you can easily (without iterating through all elements in the array) check if there are teamUser with that id.
if(teamSocketsList[TeamUser.userId]) // team user exists in the list
Related
This question already has answers here:
Group array items using object
(19 answers)
How can I group an array of objects by key?
(32 answers)
Closed last month.
I am trying to create a new array of objects by comparing two arrays.One array contains the ids to be compared and the other contains the dataset which should be compared with the first array are a new array of object must be created.
Let me explain this in detail
Consider array 1:
['1','2']
Array 2
[{name:'Linus',id:'1'},{name:'Anthony',id:'1'},{name:'Jake',id:'2'},{name:'Eva',id:'2'}]
What I am expecting as a output is:
[
{id:'1',users:[{name:'Linus',id:'1'},{name:'Anthony',id:'1'}]},
{id:'2',users:[{name:'Jake',id:'2'},{name:'Eva',id:'2'}
]
I am not sure what has to be done.
Something like this for example
const ids = ['1','2'];
const users = [{name:Linus,id:'1'},{name:Anthony,id:'1'},{name:Jake,id:'2'},{name:Eva,id:'2'}];
const groups = ids.map(id =>{
return {
id,
users: users.filter(u => u.id === id)
}
})
const groupBy = ['1','2'];
const data = [{name:'Linus',id:'1'},{name:'Anthony',id:'1'},{name:'Jake',id:'2'},{name:'Eva',id:'2'}];
const result = groupBy.map(id => {
return {
id,
users: data.filter(item => item.id == id),
}
})
console.log(result);
Try this code
This question already has answers here:
Make array objects all have the same keys
(5 answers)
Closed 1 year ago.
The community reviewed whether to reopen this question 1 year ago and left it closed:
Original close reason(s) were not resolved
I have a dynamic array which for downstream purposes needs to have all properties define for all objects.
If I have this array:
[
{"Header":"1","Apples":10},
{"Header":"2","Apples":10, "Oranges":153},
{"Header":"3","Oranges":280, "Pears":200},
{"Header":"4","Oranges":1165}
]
How do I fill it out to infill zero values for properties where they exist elsewhere in the array, but not in that object.
Essentially I need to up with this:
[
{"Header":"1","Apples":10, "Oranges":0, "Pears":0},
{"Header":"2","Apples":10, "Oranges":153, "Pears":0},
{"Header":"3","Apples":0, "Oranges":280, "Pears":200},
{"Header":"4","Apples":0, "Oranges":1165,"Pears":0}
]
Header property is essentially the id of each object
const arr = [
{"Header":"1","Apples":10},
{"Header":"2","Apples":10, "Oranges":153},
{"Header":"3","Oranges":280, "Pears":200},
{"Header":"4","Oranges":1165}
];
// get unique keys
let objWithAllProp = arr.reduce((acc, item) => ({...acc, ...item}));
// Get keys as an array and Create an object with all keys set to the default value to 0
let uniqueObjectWithAllProp = Object.keys(objWithAllProp).reduce((acc, key) => {
acc[key] = 0
return acc;
}, {});
// Replace all default values with original, so if key not present in original item, it will be available from uniqueObjectWithAllProp and value default to 0
let result = arr.map((item) => ({...uniqueObjectWithAllProp , ...item}));
console.log(result);
You can get all the existing property values by pushing each item's properties to an array (with Object.keys), then using Set and spread syntax to get the unique.
Then, map over each item in arr and in the loop, loop through the existing property values and check whether the current item has that property. If not, set the value of that property to 0.
const arr = [
{"Header":"1","Apples":10},
{"Header":"2","Apples":10, "Oranges":153},
{"Header":"3","Oranges":280, "Pears":200},
{"Header":"4","Oranges":1165}
]
const properties = [...new Set(arr.map(e => Object.keys(e)).flat())]
const result = arr.map(e => (properties.forEach(f => !e.hasOwnProperty(f) ? e[f] = 0 : ''), e))
console.log(result)
This question already has answers here:
Get all unique values in a JavaScript array (remove duplicates)
(91 answers)
Closed 1 year ago.
I have this array of objects, my aim is to remove dublicate values from values array, I want the result to be [{name:'test1', values:['35,5', '35,2','35,3']}, {name:'test2', values:['33,2', '34,3', '32,5']}]
I have tried following solution but it does not works, Do you have any suggestions? Thanks in advance
let arr = [{name:'test1', values:['35,5', '35,2', '35,2', '35,3', '35,5']},
{name:'test2', values:['35,1', '35,1', '33,2', '34,3', '32,5']}]
let uniqueArray = arr.values.filter(function(item, pos) {
return arr.values.indexOf(item.values) == pos;
})
console.log(uniqueArray)
}
}
You can easily remove duplicates from an Array by creating a new Set based off it.
Set objects are collections of values. You can iterate through the elements of a set in insertion order. A value in the Set may only occur once; it is unique in the Set's collection
If you want the result in an array, just use spread syntax for that, for example:
let arr = [{
name: 'test1',
values: ['35,5', '35,2', '35,2', '35,3', '35,5']
},
{
name: 'test2',
values: ['35,1', '35,1', '33,2', '34,3', '32,5']
}
];
const uniqueArr = arr.reduce((accum, el) => {
// Copy all the original object properties to a new object
const obj = {
...el
};
// Remove the duplicates from values by creating a Set structure
// and then spread that back into an empty array
obj.values = [...new Set(obj.values)];
accum.push(obj);
return accum;
}, []);
uniqueArr.forEach(el => console.dir(el));
i have an array of obejcts that has this structure
let events = [ {
"initDate": "2019-11-20",
"finalDate": "2019-11-22",
"intermediateDates": [
"2019-11-20",
"2019-11-21"
],
"priority": 1
},....]
So, i'm trying to get the object that matches from a given array of dates for example :
let filteredDays = [
"2019-11-20",
"2019-11-21",
"2019-11-22"
]
i'm trying with lodash like this:
let eventsFound= [];
let intersection = _.map( this.events,function(value){
let inter = _.intersection(value.intermediateDates,filteredDates);
console.log(inter);
if(inter != []){
foundEvents.push(value);
return value;
}else{
return false;
}
});
when i console log inter i get the first array with values then the next arrays are empty but it keeps pushing all the events into the foundEvents Array and the returned array is the same as the events array.
You're comparing two arrays using !=. In javascript [] != [] is always true. To check if an array is empty, use length property like arr.length == 0.
Use filter instead of using map like a forEach.
To check existance use some/includes combo instead of looking for intersections.
So, filter events that some of its intermediateDates are included in filteredDates:
let eventsFound = _.filter(this.events, event =>
_.some(event.intermediateDates, date =>
_.includes(filteredDates, date)
)
);
The same using native functions:
let eventsFound = this.events.filter(event =>
event.intermediateDates.some(date =>
filteredDates.includes(date)
)
);
So I have an array of ObjectID's, for example:
console.log(objectIdArray);
gives [ObjectID, ObjectID, ObjectID].
However there are duplicates here, as seen when mapping to ID strings:
var idArray = objectIdArray.map(objectId => objectId.toString());
console.log(idArray);
gives ["5afa54e5516c5b57c0d43227", "5afa54e5516c5b57c0d43227", "5afa54f0516c5b57c0d43228"] where you can see the ID ending in 27 is duplicated twice.
How can I filter this array of ObjectID's to remove the duplicates (keeping the complete ObjectID objects, not just the ID string values)?
const removeDuplicates = inputArray => {
const ids = [];
return inputArray.reduce((sum, element) => {
if(!ids.includes(element.toString()){
sum.push(element);
ids.push(element.toString());
}
return sum;
}, []);
};
This solution will remove all the objects that aren't the first object with a certain Id.
We fill an Array with the ids, then we check if the ids already are filled in the current list.
The above solution can be potentially slow if there is a lot of elements since you need to check the list of ids which is O(n) for each iteration in the inputArray which would put the algorithm at O(n^2)+O(n)
So instead, we can sort it first based on toString() then we can just verify that the current id didn't match the last id we saw.
const removeDuplicates = inputArray => {
const sortedArray = inputArray.sort((a,b) => (a.toString() > b.toString() ? 1 : (a.toString() < b.toString() ? -1 : 0)));
let lastSeen = undefined;
return sortedArray.reduce((sum, element) => {
if(lastSeen !== element.toString()){
sum.push(element);
}
lastSeen = element.toString();
return sum;
}, []);
};
Now the algorithm is O(n log n) + O(n) assuming sort uses Merge Sort
If you use ES6 you can take Sajeetharan's answer, but create a set of objects, not their ids:
let nodupes = [...new Set(objectIdArray)];
I recommend MongoDB Aggregation Pipeline to prevent the situation of having a final result with duplicate ObjectId values.
However:
// Define callback Function to receive modified Array
var receiveModifiedArray = function(objectIdArray) {
// log modified Array to console
console.log(objectIdArray);
}
// Remove duplicate ObjectId values
function removeDuplicateObjectIdValues(objectIdArray, callback) {
// Iterate through each ObjectId
objectIdArray.forEach((currentValue, index, array) => {
// evaluate Array items with index greater than 0
if(index > 0) {
// check ObjectId string values for type and value equality
if(currentValue.toString() == array[index -1].toString()) {
/**
* The splice() method changes the contents of an array
* by removing existing elements and/or adding new elements.
* https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/splice
*/
objectIdArray.splice(index,1);
}
// If processing last item in Array, callback
if(index == array.length +1) {
callback(objectIdArray);
}
}
});
// Return to move on to next message in call stack
return;
}
// Remove duplicate ObjectId values
removeDuplicateObjectIdValues(objectIdArray,receiveModifiedArray);