1

I have this array of objects that i display on the UI table. It has 3 columns with name, contact and id.

[Object, Object, Object]
0:Object
    name: "Rick"
    Contact: "Yes"
    id: 1
1:Object
    name:"Anjie"
    Contact:"No"
    id: 2
2:Object
    name:"dillan"
    Contact:"Maybe"
    id:3

Now, i add a new row to the top of table. So the newly added row into the array of objects, would look like this.

[Object, Object, Object,Object]
0:Object  //newly added row. Since new row is added, it doesnt have any data.
 name: ""
 Contact: ""
 id: 
1:Object
 name: "Rick"
 Contact: "Yes"
 id: 1
2:Object
 name:"Anjie"
 Contact:"No"
 id: 2
3:Object
 name:"dillan"
 Contact:"Maybe"
 id:3

I want the array of objects to look like this instead of above one.

[Object, Object, Object,Object]
0:Object  //newly added row. Since new row is added, it doesnt have any data.
 name: ""
 Contact: ""
 id: 4        
1:Object
 name: "Rick"
 Contact: "Yes"
 id: 1
2:Object
 name:"Anjie"
 Contact:"No"
 id: 2
3:Object
 name:"dillan"
 Contact:"Maybe"
 id:3

The only change is id value at 0th object. You can see i entered it as 4. It will check the max value in array of objects for id. In this case, it is 3. So it will increment by 1 and put it as the id value for newly added row.

Can someone let me know how to achieve this please.

Also, I had one more query.

If my id values are as follows.

1
2
3
4
5
6

And i delete 4 and 5. So new rows will be

1
2
5
6

Here, it will check max length as 4 and add id value of 5 to newly row. it will look somewhat like this.

5
1
2
5
6

In this case, 5 is repeated. I dont want this. I instead would like to see which is the highest value given to id, and then increment the id according to it. So it should look like this.

7
1
2
5
6
0

3 Answers 3

4

If I understand you correctly, you simply want to run:

array[0].id = array.length;

immediately after adding the row. Alternatively, if you can control the values of the object representing the new row when it is added, you could add the row as:

{
  name:"",
  Contact:"",
  id: array.length + 1
}

EDIT:

In response to your edit, showing that rows of the array can be deleted.

In that case, to get the ID value, you have a number of options.

One is to go through all members of the array at time of deletion, and reduce the id of all rows which have an id greater than the deleted row. This is probably the best solution.

Example code:

var delete = function(array, idToDelete) {
  for(var i = 0; i < array.length; i += 1) {
    if(array[i].id === idToDelete) {
      array.splice(i, 1);
    } else if (array[i].id > idToDelete) {
      array[i].id = array[i].id - 1;
    }
  }
}

If, for whatever reason, this is not an option, I would reccommend iterating through the array to find the highest ID in it, and adding 1.

var newId = array[0].id;
for(var i = 0; i < array.length; i += 1) {
  if(array[i].id > newId) {
    newId = array[i].id;
  } 
}
array.splice(0, 0, {name:"", Contact:"", id: newId + 1});
Sign up to request clarification or add additional context in comments.

4 Comments

array.length - 1 in the second approach? ;)
Nope, look at OP's question. His ids are 1-indexed, for whatever reason. Also, in the second approach, no, it's +1. Think about it; when adding the first item, the length of the array would be 0, but the desired id would be 1.
Oh, okay . . . I misunderstood your description . . . my bad (i.e., I thought "when it is added" = "it has already been added"). And then I screwed up the math . . . you know what . . . just ignore it. :D
@MaxGorenberg- i edited my question as there was a problem if i just took the max length. can you help me how to get this new test case solved.
3

You can use this to find the next highest ID available (assuming that it's not trivially always equal to the length of the array):

var newID = 1 + myArray.reduce(function(p, c) {
    return Math.max(c.id, p);
}, 0);

where myArray is your array.

In ES6 you could use:

var newID = 1 + myArray.reduce((p, c) => Math.max(c.id, p), 0)

7 Comments

If you're going to iterate anyway, why not .reduce()? Seems a little wasteful use a function to make an Array of values to pass to Math.max instead of just determining the maximum value right in the function.
@squint I've shown it, although it's possibly harder to understand. It also shows that there's an issue with the Math.max version if passed an empty array. Hmm...
@Alnitak: There shouldn't be an issue with an empty array if you pass the seed like you're doing, though I was thinking more like (p, c) => c.id > p ? c.id : p. Either way works though.
@Patrick the whole point of this answer is that it takes the existing values into account. I've now removed the Math.max based versions since they had a nasty edge case when the given array is empty.
@squint yeah, it's fine if you pass 0 as the seed. The problem with Math.max by itself is that given an empty array it returns -Infinity. I went for Math.max within .reduce instead of the ternary operator because it avoids the double repetition of the terms.
|
-1

If you only care about the ID being unique, you can add the timestamp as the ID

Lets assume that your array is called peopleContact your code to add the item in the array of objects would look something like the following.

var person= new Object();
person.name= "";
person.Contact= "";
person.id = Date.now();

peopleContact.push(person);

8 Comments

wow. never thought of this. this would be the best thing to do for my case.
@Patrick: Are you sure you can guarantee that you'll never push more than one object into the Array during the same millisecond?
Be careful - JS is fast enough that if you're not waiting for some other interaction that two IDs could be generating within the same millisecond
@Alnitak, I agree, Although there are few chances of that happening, it can happen. Patrick, If you think that this can happen you can do something like get the users IP Address from the server side when they open the page, strip the "." from them and concatenate them with the ID. If you like, I can show you how to do it. Or even concatenate the array length at the end. If 2 users can click at the same time, the array length can also turn out to be the same. In this case, the IP address idea is the only one that might work. Any Thoughts or suggestions ?
@Patrick: If your concern was having to iterate the array to get the highest id, you'd be much better off just closing over a serial number and incrementing it with every addition.
|

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.