How to find the highest field value in a collection - javascript

For example, say I have these documents in a collection named "items":
{
rank: 1
}
{
rank: 2
}
{
rank: 3
}
How would I find the highest rank value (3) in the items collection to be assigned to a variable?

You can sort the documents by rank and limit to one item.
MyCollection.findOne({}, {sort:{rank:-1}, limit: 1}); // Document with max rank
MyCollection.findOne({}, {sort:{rank:+1}, limit: 1}); // Document with min rank
So you get your max rank value like that:
var maxRank = MyCollection.findOne({}, {sort:{rank:-1}, limit: 1}).rank;

You can use this:
var arr = [{
rank: 1
},
{
rank: 2
},
{
rank: 3
}];
var max;
for (var i=0 ; i<arr.length ; i++) {
if (!max || arr[i].rank > max){
max = arr[i].rank;
}
}
console.log(max);

Related

How to get lastindexof an array using key value pair [duplicate]

This question already has answers here:
indexOf method in an object array?
(29 answers)
Closed 3 years ago.
I am trying to get the last index of a value in an array of objects.
I am unable to make it work; I am expecting the lastIndexOf an element id with value 0.
var sample = [
{
id: 0,
name: 'abbay',
rank: 120
},
{
id: 1,
name: 'sally',
rank: 12
},
{
id: 0,
name: 'abbay',
rank: 129
}
];
var index = this.sample.lastIndexOf(0{id});
Argument of type '0' is not assignable to parameter of type '{id: number; name: string; rank: number;}'.
You can map into an array of booleans:
var lastIndex =sample.map(s =>
s.id === 0).lastIndexOf(true);
then access your array by last index:
console.log(sample[lastIndex]);
Array's lastIndexOf method compares searchElement to elements of the Array using strict equality (the same method used by the ===, or triple-equals, operator). If your array contains objects, then you have to use another method.
If performance is not important and the amount of data is not that big, you can use
const lastIndex = sample.length - 1 - sample
.slice()
.reverse()
.findIndex( item => item.id === 0 );
slice will create a copy of the array, reverse will reverse it, findIndex will return the first item that matches o.id === 0 and the final result is subtracted from sample.length - 1. It's not very efficient for a large data set.
Or you can use a plain for
function findLastIndexOf(arr) {
for (let i = arr.length; i--;) {
if (arr[i].id === 0) {
return i;
}
}
}
findLastIndexOf(sample);
for (let i = arr.length; i--;) looks weird but it will start iterating from the last position and stop when i reach the value of 0. Give it a try.
Hope it helps
Try this:
const lastIndex = sample.map(res=>res.id).lastIndexOf(0) // id = 0
console.log(lastIndex) // 2
const lastIndexWithIdZero = this.sample.length - this.sample.reverse().findIndex(i => i.id === 0);
if (lastIndexWithIdZero > arrLen) {
throw new Error('didn\'t worked');
}
forget that, it's slow, better use just
let lastIndexWithIdZero = -1;
for (let i = 0, v; v = sample[i]; i++) {
if (v.id === 0) {
lastIndexWithIdZero = i;
}
}
console.log(lastIndexWithIdZero);
http://jsben.ch/LY1Q0
You could filter the results, then reverse the results and grab the first item.
const sample = [{
id: 0,
name: "abbay",
rank: 120
},
{
id: 1,
name: "sally",
rank: 12
},
{
id: 0,
name: "abbay",
rank: 129
}
]
console.log(
sample
// Add the index to the object
.map((i, idx) => ({id: i.id, idx}))
// Filter the object where id == 0
.filter(i => i.id == 0)
// Reverse the result and get the first item
// Get the idx
.reverse()[0].idx
)

looping through object and mapping to a new object in a specific order

I have a variable that looks like this:
var objList = [{variantId: "1111", quantity: 2},
{variantId: "222222", quantity: 2},
{variantId: "333333", quantity: 2},
{variantId: "44444", quantity: 1}]
I am looking to write a function that takes in a number between 1 and all of the quantities added together ( in this example 7 ) then it will contstruct a new variable that has a total quantity of the input
Items will be added in this order:
variantId:1111 - add one of these to the new variable
variantId:2222 - add one of these ""
variantId:3333 - add on of these ""
variantID:4444 - add the only one of these
variantID:1111 - add the second one of these to new variable
variantID:2222 - add the second one of these ""
variantID:3333 - add the second one of these ""
the function will look something like this.
function(x){
var newObj = [];
var i=0;
while(i<x){
//logic to add the necessary item from the objList
// really struggling here
i++;
}
return newObj;
}
Iterate the array while you still have space in your inventory
Check that the current item still has quantity
If it doesn't, skip it
If it does, decrement the item's quantity and add that item to inventory
Return the inventory
Consider this code:
const objList = [{
variantId: "1111",
quantity: 1
},
{
variantId: "222222",
quantity: 2
},
{
variantId: "333333",
quantity: 2
},
{
variantId: "44444",
quantity: 1
}
];
function distribute(list, count) {
// Track our distributed items
const ret = [];
// Clone and reverse the array input the array for good measure
let clone = list
.map(item => Object.assign({}, item))
.reverse();
// Start idx at the "begining"
let idx = clone.length - 1;
// Iterate through the inventory while we have room and items
while (count-- && clone.length) {
// Push the current item
ret.push(clone[idx].variantId);
// Decrement the quantity of items
clone[idx].quantity--;
// If we are out of the item, remove it
if (!clone[idx].quantity) {
clone.splice(idx, 1);
}
// Go to the next item
idx--;
// If we reach the "end" of the inventory
if (!idx) {
// Go back to the "begining"
idx = clone.length - 1;
}
}
// Return our parceled items
return ret;
}
// Test it
console.log(distribute(objList, 5))

How can I change the index order of an array?

I have a button that has a function called clickNext(). Whenever that button is clicked, it increments the index position (scope.selected) on an array called 'arr1'.
<button type="button" class="right-btn col-xs-6" role="menuitem" ng-click="clickNext()">Next</button>
.
function clickNext()
{
scope.selected = (scope.selected + 1) % length;
}
arr1 = [
{apple: 1 , tango},
{banana: 3, kappa},
{orange:5, alpha},
{apple: 8 , beta},
{grape: 10 , sigma}
]
Problem
I have an identical array to arr1 called 'arr2'. What I'm trying to do is have the clickNext() increment to the next index position based on the arr2 array instead of the arr1 array.
Right now, the clickNext function still increments in the order of the arr1 array. For example, if I were to click the button, it would start on orange:5 then move to apple 8, etc.
arr2 = [
{orange:5, alpha},
{apple: 8 , beta},
{banana: 3, kappa},
{grape: 10 , sigma},
{apple: 1 , tango}
]
What I have tried
My though process to accomplish this is to use the findIndex() function and match the arr2 item to the arr1 item. That doesn't work, but maybe I'm structuring it wrong?
clickNext(){
var oldIndex = filteredToXs(scope.selected);
scope.selected = oldIndex + 1;}
function filteredToXs( filteredIndex ) {
var firstArr = scope.arr1[ filteredIndex ];
var xsIndex = scope.arr2.findIndex( function(item) {
return item.trackingNumber === firstArr.trackingNumber;
} );
if( xsIndex >= 0 ) return xsIndex;
if( xsIndex === -1 ) return 0; // Default value
}
I hope I understood your question correctly. Please read my comments in the code sections as well.
I had to modify your source so I was able to create a fiddle for you.
HTML: I changed the click event and removed a css class that's not available
<button type="button" role="menuitem" onclick="clickNext();">Next</button>
Sampe Arrays:
They were containing invalid objects: I changed alpha, beta, tango, .. to a property. You can also define them as values.. this shouldn't matter:
var arr1 = [
{ apple: 1, tango: '' },
{ banana: 3, kappa: '' },
{ orange: 5, alpha: '' },
{ apple: 8, beta: '' },
{ grape: 10, sigma: '' }];
var arr2 = [
{ orange: 5, alpha: '' },
{ apple: 8, beta: '' },
{ banana: 3, kappa: '' },
{ grape: 10, sigma: '' },
{ apple: 1, tango: '' }];
Code:
var idx = 0; //save current index of array 2
function clickNext() {
idx++;
//I'm comparing the array objects using a string compare- this only works because you said 'I have an identical array'
//this may cause issues if you're objects are cross-referenced
var find = function(array, obj) { //lookup value from arr2 in arr1
for (var i=0, l=array.length;i<l;i++)
if (JSON.stringify(array[i]) == JSON.stringify(obj)) //adjust this line to your needs
return array[i];
}
var result = find(arr1, arr2[idx])
if (!result)
throw new Error('not found- your arrays are not identical or you run out of index');
console.log(result);
}
fiddle: https://jsfiddle.net/k50y8pp5/

Parsing this table with Javascript into array of objects

I have this source table data:
And I would like to get data parsed like this (grouped by row):
I grouped source table into an array of objects.
This is my array:
[ { rowId: 4, colId: 10 } { rowId: 4, colId: 11 } .... ]
Now I would like to get an array of parsed objects..
How can I do this?
I parsed the array with a for loop but I got some error when I create the new array of objects..
My code:
for (var i=0; i<tableArray.length; i++) {
if (tableArray[i].rowId != rowLast) {
bar = true;
var row = tableArray[i].rowId;
var start = tableArray[i].colId;
}
if ((bar)&&(tableArray[i].colId != colLast)) {
var end = tableArray[i].colId;
tab = { row: row, start: start, end: end }
newTableArray.push(tab);
bar = false;
}
rowLast = tableArray[i].rowId;
colLast = tableArray[i].colId;
}
Help! I'm a bit confused in loop :(
Many thanks.
You could group the elements and use an object for the last values. This solution needs sorted data.
var array = [{ rowId: 4, colId: 10 }, { rowId: 4, colId: 11 }, { rowId: 4, colId: 12 }, { rowId: 4, colId: 20 }, { rowId: 4, colId: 21 }, { rowId: 6, colId: 6 }, { rowId: 6, colId: 7 }, { rowId: 6, colId: 8 }, { rowId: 7, colId: 12 }, ],
group = [];
array.forEach(function (a, i) {
if (!i || // group changes if first object i = 0
this.last.row !== a.rowId || // or different rowId
this.last.end + 1 !== a.colId // or not in sequence
) {
this.last = { row: a.rowId, start: a.colId, end: a.colId };
group.push(this.last);
}
this.last.end = a.colId;
}, {});
console.log(group);
I would rather write a function to generate the new array, I hope the comments explain the thought process behind it:
function transform(array) {
var output = [];
// initiates the first object you want in your output array
// with the row and colId of the first object from the input array
var obj = {
row: array[0].row,
start: array[0].colId,
end: array[0].colId
};
// Loop starts at 1 instead of 0 because we used the first object array[0] already
for (var i = 1; i < array.length; i++) {
var current = array[i];
// if the current objects row is still the same,
// AND the colId is the next colId (meaning no spare cols between)
// set the new objects end to this colId
if(obj.row === current.row && (current.colId - obj.end) === 1 ){
obj.end = current.colId;
}
// when the row does not match, add the object to the output array and
// re-innitiate it with the current objects row and colId
else {
output.push(obj);
obj.row = current.row;
obj.start = current.colId;
obj.end = current.colId;
}
}
// Once the loop is done, add the last remaining object to the output array
output.push(obj);
return output;
}

How to sum the price grouped by some variable in jquery

The first list in image shows what I have achieved after loop. Now I want sum of "pay" grouped by "organizationid" as shown in the second list.
I only need the second list to be saved in database but could not achieve it with JQuery.
How can I get the sum grouped by organizationid using jquery?
You can loop through the array and aggregate them to another object:
var input = [
{ oId: 1, pay: 10 },
{ oId: 1, pay: 10 },
{ oId: 2, pay: 20 },
{ oId: 2, pay: 20 },
{ oId: 3, pay: 30 }
];
var result = {} ;
for (var i = 0; i < input.length; i++) {
var rec = input[i];
if(result.hasOwnProperty(rec.oId))
result[rec.oId] += rec.pay;
else
result[rec.oId] = rec.pay;
}
return result;

Categories

Resources