0

I have a javascript array that contains objectiveDetail objects.

objectiveDetails[]

Here I am adding a new objectiveDetail:

var emptyObjectiveDetail = {
  "number": formData.objectiveDetails.length +1, // I want to change this !
  "text": "", 
  "response": false, 
  "objectiveId": formData.objectiveId
};
objectiveDetails.push(emptyObjectiveDetail);

How can I make it so that the number I assign to the emptyObjectDetail field is equal to the greatest number currently used by the objectiveDetail objects in the array.

In other words if I have three objectiveDetail objects with the "number" field set to 1, 4 and 5 then when I add a new object I would like to add it with the number 6 instead of the length of the array + 1

I'm also interested in using _underscore and would like to know if there is a good way to do this with underscore as well as javascript

Vijay
  • 8,131
  • 11
  • 43
  • 69
Alan2
  • 23,493
  • 79
  • 256
  • 450

5 Answers5

2

Try the below sample.

Basic idea is create a dummy single dimensional array with only the number values of the objectiveDetails array using the .map function and then use Math.max to find the max value in that dummy 1D array.

var maxNum  = Math.max.apply(Math,objectiveDetails.map(function(o){return o.number;}));
var emptyObjectiveDetail = {
    "number": maxNum+1,
  "text": "", 
  "response": false, 
  "objectiveId": 123
};
objectiveDetails.push(emptyObjectiveDetail);
Harry
  • 87,580
  • 25
  • 202
  • 214
1

If I understood the question right and formData.objectiveDetails only contains numeric values, I think you can use Math.max to determine the maximum value:

var emptyObjectiveDetail = {
  "number": Math.max.apply(null,formData.objectiveDetails) + 1,
  // etc.
};
KooiInc
  • 119,216
  • 31
  • 141
  • 177
0

You could try

var emptyObjectiveDetail = {
  "number": objectiveDetails[objectiveDetails.length-1].number + 1, // I want to change this !
  "text": "", 
  "response": false, 
  "objectiveId": formData.objectiveId
};
objectiveDetails.push(emptyObjectiveDetail);

It will make the key 'number's value equal to the last number entered.

To truly find the largest, though, you'll have to iterate through all the values and find the largest 'number'.

Joe Simmons
  • 1,828
  • 2
  • 12
  • 9
  • Yes I do need the largest but I am not sure the best way to iterate through all the values. – Alan2 Aug 10 '13 at 08:32
  • you could add duplicates by adding fixed number 5, fixed number 4 and dynamic next will also have number 5... – iRaS Aug 10 '13 at 08:32
  • I am not sure what you mean "add duplicates". I need to add new emptyObjectiveDetails that are empty except for the "number" field being one bigger than the highest currently used. – Alan2 Aug 10 '13 at 08:40
  • @Alan yes, and with this code you will add the number 5 two times if you previously add an item with a fixed number 4. This code is something like: number = latest+1 But you still can add an object with: number = 4 After adding an item with a fixed number latest+1 may be existing already.. – iRaS Aug 10 '13 at 08:49
  • These are discrete requests. When a request comes in I need to check what is the highest number and then create a new object with that. THen later another request comes in and I need to again iterate through objectiveDetails[] and check. – Alan2 Aug 10 '13 at 09:01
0

This is my suggestion:

// create an empty array
var objectiveDetails = [];
// set the current highestNumber to 0
objectiveDetails.highestNumber = 0;
// add a custom method to add an objectiveDetail
objectiveDetails.add = function(objectiveDetail) {
    // if objectiveDetail is not given make an empty object
    objectiveDetail = objectiveDetail ? objectiveDetail : {};
    // if objectiveDetail.number is not given give it highestNumber+1
    if (!objectiveDetail.number) {
        objectiveDetail.number = objectiveDetails.highestNumber + 1;
    }
    // check if highestNumber is still the highest
    if (objectiveDetail.number > objectiveDetails.highestNumber) {
        objectiveDetails.highestNumber = objectiveDetail.number;
    }
    // add objectiveDetail to array
    objectiveDetails.push(objectiveDetail);
}

examples:

var emptyObjectiveDetail = {
  "number": 3,
  "text": "", 
  "response": false, 
  "objectiveId": 412
};
objectiveDetails.add(emptyObjectiveDetail);

var emptyObjectiveDetail = {
  "number": 2,
  "text": "", 
  "response": false, 
  "objectiveId": 413
};
objectiveDetails.add(emptyObjectiveDetail);

var emptyObjectiveDetail = {
  "text": "", 
  "response": false, 
  "objectiveId": 414
};
objectiveDetails.add(emptyObjectiveDetail);

var emptyObjectiveDetail = {
  "number": objectiveDetails.highestNumber+1,
  "text": "", 
  "response": false, 
  "objectiveId": 414
};
objectiveDetails.add(emptyObjectiveDetail);

console.log(objectiveDetails);
iRaS
  • 1,958
  • 1
  • 16
  • 29
  • I am not sure I understand your code. What I need is to find out the highest value of the "number" field and then use this in: "number": // highest number here. I think the main thing is to iterate through the existing but I am not sure how best to do that. – Alan2 Aug 10 '13 at 08:47
  • highestnumber will be used in the add method - you could also use the highestnumber outside.. I'll add an example – iRaS Aug 10 '13 at 08:50
  • Can you tell me how you iterate through the array. Is it here "objectiveDetail ? objectiveDetail : {};" Also will this work if there are no objective details. Will it still add one with the number set to 1 ? – Alan2 Aug 10 '13 at 08:53
  • "objectiveDetail ? objectiveDetail : {}" is just to prevent error messages. I do not iterate. I create a custom method add(obj) this method checks if highestNumber is less than obj.number and sets the highestNumber to obj.number if true. – iRaS Aug 10 '13 at 08:57
  • But where do you go through each existing objectiveDetail to find out the one with the highest value in its "number" field? These are discrete requests. I won't be holding the highest number in a variable ready for next time. – Alan2 Aug 10 '13 at 08:58
  • iRaS - Sorry but I'm not sure I understand what you are suggesting. Every time I add a new object it's another event. Might happen an hour later. I might do a delete after adding and then I would need to add again and just use the same number. There is no objectiveDetails.highestNumber field and I cannot just add that as another field as it would pollute the object. – Alan2 Aug 10 '13 at 09:03
  • so there is a page reload between each adding? Maybe you should be more specific in you question – iRaS Aug 10 '13 at 09:09
  • Yeah sorry for not adding as much detail. It's a web application responding to a user clicking "add" – Alan2 Aug 10 '13 at 09:28
0

I believe there are 2 other ways besides the ones already suggested:

1) (Most efficient) : Store the values in a number (maybe as a global or as a variable withing the class). Keep updating it as you add objects. While adding the new object check this number and add object accordingly.

Advantage : Most efficient in terms of computation. No need to go through all of the objects while adding a new object.

2)(Optimised I believe) : Ok here it is using underscore and I believe it is optimized :D

var maxNum = _.max(objectiveDetails,function(objectiveDetail){return objectiveDetail.number;});
var emptyObjectiveDetail = {
    "number": maxNum+1,
  "text": "", 
  "response": false, 
  "objectiveId": 123
};
objectiveDetails.push(emptyObjectiveDetail);

Advantage : Using a library which has been optimized for this kind of stuff.

Hope that helps :)

woofmeow
  • 2,370
  • 16
  • 13