Google Scripts 2D Array sorting by value - javascript

I have a 2d array that I am attempting to sort.
The array is typically accessed with this structure: array[r][c].
I want to re-order the values of array, so that each [r] value is sorted by the 4th c value.
Looking online, I've seen a few sorting scripts that seem to work for other structured arrays, but I'm wondering if i'm missing something stupid.
The array is structured so that for each 'r' value in array, there is a list of values, depending on what 'c' value you put in (eg: if you do array[0][2] that will be the first entry's address, and array[0][10] is the first entry's phone number).
I want to be able to sort based off of c values 4 and... 10 (for example). (ideally, I'd sort by multiple columns, such as sort by last name first, then by first name--but i'll settle for one sort for now hahaha )
I'm not certain if any of the default sort functions would work for me, or if i need to write out a manual sort function (which i'm hoping i do not have to do as that would be fairly inefficient).
Thanks for any pointers

You'll need to write your own compare function.
Snippet:
const COLTOSORT = 2;
function compare(row1, row2) {
return row1[COLTOSORT] < row2[COLTOSORT]
? -1
: row1[COLTOSORT] > row2[COLTOSORT]
? 1
: 0;
}
array.sort(compare);
References:
Array#sort

Related

I need help understanding this algorithm solution of Top k frequent element

I am having trouble understanding the last line of this algorithm specifically the inside of the sort method, I don't understand why b[1] is being subtracted by a[1] I tried working through the return statement one step at a time: I know that at Object.entries(storage) I should have an array with 3 arrays inside like so [[1,4],[3,3],[2,1]] I then console logged b[1] to see what it would be and it gave me 4 from the first array and 3 from the second array then I console logged a[1] and the output was 3 from the second array and 2 from the third array so I'm really confused as to why they don't even start from the same index which would be [1]. If I'm not clear or if I'm missing any information let me know and I will try to update my question quickly
The testcase I'm using is nums=[1,1,1,1,3,3,3,2,2] and k=2
the original question in leetcode
var topKFrequent = (nums, k) => {
let storage = {}
for(let num of nums){
storage[num] = (storage[num] ?? 0) + 1
console.log(storage[num],'tset')
}
return Object.entries(storage).sort((a,b) => b[1] -a[1]).map(val=>Number(val[0])).slice(0,k);
}
I'm really confused as to why they don't even start from the same index which would be [1]
The sort method decides "on its own" which two values (two little subarrays in this case -- I will refer to them as "elements") from the input array it will pass as arguments to your callback function. We are not supposed to be concerned by that choice.
Realise that the internal sort algorithm will call your callback function when it wants to know how two elements from the given array compare.
It is normal that this internal sort algorithm will select a and b as two different elements, as it doesn't need to know how the first element compares with itself. It needs to know how two distinct elements compare and for that it will call your callback function. a and b could really be elements at any index in your array, and in subsequent calls of the callback those indices don't have to follow a certain order. It really could be any pair from the array depending on which algorithm the sort method uses. It could in theory even decide to start with the last two elements in your array...
Although we could dive into the source code of the JavaScript engine we are working with (like V8) to determine what a and b would be when the callback is called, it really shouldn't be of our concern. All we are responsible for is to have the callback answer the question how the given a and b compare.
We do this by:
returning 0 when we want a and b to be treated as equal in the sorting order,
returning a negative number when we want a to be ordered before b in the result (we define that a is "less than" b)
returning a positive number when we want a to be ordered after b in the result (we define that a is "greater than" b).
As long as the sorting algorithm doesn't have enough information to complete the sort, it will call the callback to get more info. All the rest of the sorting algorithm is taken care of by the sort method implementation.
Well, given [[1,4],[3,3],[2,1]], it first compares a = [3,3] with b = [1,4]. Your "same index" sounds like you expect it to compare [1,4] with itself? Anyway, b[1] - a[1] = 4-3 = 1 is greater than zero. The sorting algorithm really is ascending, so "greater" means "belongs on the right". So you're telling it that [3,3] belongs to the right of [1,4].
In the second comparison, you're telling it that [2,1] belongs to the right of [3,3].
That's all the sorter needs to know. The only possible order is [[1,4],[3,3],[2,1]].
After that, the map extracts the first number of each pair: [1,3,2]. And then the slice gives you the first k of those, e.g., [1,3] if k=2.
The part after => and before the ) is your compare function. In your case:
b[1] - a[1]
Subtracting your sort values (a,b) makes sort compare numbers instead of strings. The sort order (ascending/descending) depends on comparing b subtracted from a or a from b. Your function assumes there are no Infinity or NaN in the array.

Double sort list in react-native

I'd like to know how to "double sort" items in react native in order to obtain a double criteria sorted list.
The data I receive from BE is a list of match: every match is an object containing 2 players, a time and a competition.
I d'like to sort items by time (so that a today match is showed before a tomorrow match) and by competition (so that a more important competition is showed before a lower one).
If two or more matches are played on the same day and within the same competition, the earlier match is showed before.
A schema better shows what I mean: I'd like to customize the UI oc the day-row, the competition-row and the match-row.
The data I receive from BE are formatted in this way:
How could I obtain what I want? I've tried with sortable list but with no result.
TY in advance
The javascript docs for sort show that you can sort using an arbitrary function. I would write a function which first compares days and then compares competitions:
function compareByDayThenByCompetition(a, b) {
if (a.day < b.day) {
return -1;
}
if (a.day > b.day) {
return 1;
}
return a.competition - b.competition;
}
events = [{day:3, competition:2}, {day:3, competition:3}, {day:3, competition:1}, {day:2, competition:1}]
console.log(events.sort(compareByDayThenByCompetition))
The best way to filter such data is.
Filter the complete list and make an array of object the object should be grouped by same timestamp.
2)Now iterate the filtered object array and filter the object value.

Incorrect operation of the sort () method on Node v.8.1.3?

There is an array at the input
['1:nnn','1:vvv','2:zzz','1:yy','1:cc','2:xx','2:uu','2:tt','2:qq','2:aa','1:ff','1:ll','1:pp']
You must specify a comparator in the sort () method so that the array is sorted according to the following principles:
1) Keep the original sorting by the length of the elements (do not interchange elements of different lengths, for example, elements 1: nnn and 1: yy)
2) If the elements are the same length, then compare the first character of each element, first the elements with the prefix 1 must go, then the elements with the prefix 2.
I tried to write the following code, but I can’t understand why it does not work as I would like on Node v.8.1.3? The incorrect result that I get looks like this:
['2:uu','1:nnn','1:ll','1:yy','1:cc','2:xx','1:ff','2:tt','2:qq','2:aa','1:vvv','2:zzz','1:pp']
If I run the code in a browser or in stackoverflow, then I get the expected result:
["1:nnn","1:vvv","2:zzz","1:yy","1:cc","1:ff","1:ll","1:pp","2:xx","2:uu","2:tt","2:qq","2:aa"]
What could be the problem and what am I doing wrong?
let output=['1:nnn','1:vvv','2:zzz','1:yy','1:cc','2:xx','2:uu','2:tt','2:qq','2:aa','1:ff','1:ll','1:pp']
output.sort((a,b) => {
if(a.length===b.length) {
if ((+a.slice(0,1))<(+b.slice(0,1))) return -1
else return 1
} else return 0
})
console.log(output)
You need a symetrically sorting and not a boolean value for only returning one or two values.
Array#sort expects three values, depending of the wanted and given order, but your result misses one value, which might be important, depending on the sort algorithm of the implementation.
Instead, you could return the delta of the values and get a perfect sorted result, independent of the implementation.
let output=['1:nnn','1:vvv','2:zzz','1:yy','1:cc','2:xx','2:uu','2:tt','2:qq','2:aa','1:ff','1:ll','1:pp']
output.sort((a, b) => b.length - a.length || a.split(':', 1) - b.split(':', 1));
console.log(output);

Finding the maximum property under a value

I have a list of objects, each with its properties.
I am trying to find a specific object in this list with this .find although I can't figure out how to find the maximum value of one of it's properties under a certain value.
let x = this.state.pricing_adjustments_view.filter((e) => {
return e.location_id === this.state.selectedLocation,
e.car_model_id === this.state.selectedCar,
moment(e.calendar_day).isSame(this.state.from, "day"),
_.max(e.minimum_duration) <= duration
})
Here it's the e.minimum_duration. I want to find the biggest value, but that is under "duration"
I am trying it with "lodash", here represented by the "_".
I am open to other possibilities.
this.state.pricing_adjustments_view is an array of objects, and you could say that for each object, the "UNIQUE" key is its "location_id", "car_model_id", "calendar_day" and "minimum_duration".
So there are several objects that are the same if we only consider "location_id", "car_model_id", "calendar_day", and then they have different "minimum_duration". I need to get the one that has the highest "minimum_duration".
Ok,
You say it's the minimum_duration that interests you. In order to find the biggest (or smallest..) It's simple to just order pricing_adjustments_view by minimum_duration and take it's highest value.
So you can basically do following using lodash lib.
// sort dataa..
let sorted = _.sortBy(this.state.pricing_adjustments_view, 'minimum_duration');
// take last in list!
let has_highest_minimum_duration = sorted[sorted.length-1];

How to sort an an object in javascript by number value

I am trying to sort an object so that the property with the most votes comes first. Here's my data structure
I have found some articles on how to do this and I have created a new array and am pushing the votes value into it as well as the player object. The problem I am having is then sorting the options by the number, and removing the votes count from the array. Here's my code
var sortedOptions = [];
for (let option of options) {
sortedOptions.push(option, option.votes);
}
sortedOptions.sort(function(a, b) {
})
I have been following this but I don't understand how the sort function is working and how to do it for my purposes.
Thanks for your help :)
EDIT:
I tried doing the following code, however this was returning an object with 8 options and the object isn't sorted
sortedOptions.sort(function(a, b) {
return a.votes - b.votes;
})
Resulted in
You can use Array.prototype.sort()
The sort function takes a function as an argument, which compares two elements of the array to determine which one should be sorted where.
For your case where you want to sort based on votes you write it like so:
options.sort(function(a, b) {
// use b - a to sort descending, a - b to sort ascending
return b.votes - a.votes;
})
The for-loop you are using is strange: it produces an array which is mixed of objects and numbers, that's why the sort function doesn't work on it. Either sort on options directly, or if you need a copy use let sortedOptions = JSON.parse(JSON.stringify(options));

Categories

Resources