1

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.

11
  • post your input Commented May 30, 2019 at 11:52
  • 1
    {"userId":1,"socketId":"M8xzpi3O0cMHXe-dAAAK"} is different from {"userId":1,"socketId":"ZIbgYMLOda_R5QqvAAAN"}. What is the criteria for keeping the first instead of the next one? Commented May 30, 2019 at 11:54
  • Inputs are from the actual results shown @KunalMukherjee Commented May 30, 2019 at 11:56
  • 1
    array.filter(function (obj) { return !this[obj.userId] && (this[obj.userId] = true); }, {}) Commented May 30, 2019 at 12:31
  • 1
    Note that inArray won't match a numeric value, held in a variable called userId, with an object with a property named userId holding the same value. Commented May 31, 2019 at 11:24

4 Answers 4

0

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.

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

Comments

-1

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);

Comments

-1

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]))
        

Comments

-1

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

5 Comments

Although it does not try to answer to OP question I have to point out that this is exactly the way I would implement it to solve the issue before it's generated
That would be resulting in storing inconsistent data structure with Team Socket List: [null,{"userId":1,"socketId":"cIoxHto6yK7vw_WeAAAM"},null,null,null,null,null,null,null,{"userId":9,"socketId":"FBVi7peHCrL6r4YcAAAO"}] @MosèRaguzzini
when retrieving socket list it wil suffice to apply a simple filter: [].filter(o => o) to get rid of null values.
I'm surprised that after getting rid of null values still stores the duplicate data Team Socket List: [{"userId":9,"socketId":"iYdg8Hpq__dV-tyFAAAJ"},{"userId":1,"socketId":"gQQ247cGqcnFOaX7AAAN"},{"userId":9,"socketId":"vYD0A5UzTCwfFHtgAAAL"},{"userId":9,"socketId":"vYD0A5UzTCwfFHtgAAAL"}] @MosèRaguzzini
@Nishanthॐ it means that the array already held those values.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.