Below is a list of array.I want the strings in array sorted only by airlines. For example below are my
airlines
"0:"FZ|Fly Dubai "1:"LH|Lufthansa "2:"IX|Air India Express
"3:"6E|IndiGo
Expected output should be which is sorted only by arilines ( Air
India Express, Fly Dubai, Lufthansa, Indigo instead of complete
string
"0:"IX|Air India Express "1:"FZ|Fly Dubai "2:"LH|Lufthansa
"3:"6E|IndiGo
I have tried something like this
str = str.split('|');
str = str.sort(function (a,b) {
if (a === '0' || b === '0')
return (b === a) ? 0 : (a < b) ? 1 : -1;
return (a < b) ? -1 : (a === b) ? 0 : 1;
});
let airlines = [
"FZ|Fly Dubai",
"LH|Lufthansa",
"IX|Air India Express",
"6E|IndiGo",
];
let sorted = airlines.sort(function(a, b) {
return a.split('|')[1].localeCompare(b.split('|')[1]);
});
console.log(sorted);
No jQuery needed.
Assuming s = '"0:"FZ|Fly Dubai "1:"LH|Lufthansa "2:"IX|Air India Express "3:"6E|IndiGo'
s.split(/\"[^\"]+\"/) // regex parses entries
.filter( // removes invalid entries
function(a){
return a.length > 0 && a.indexOf("|") > -1
}).sort( // sorts based on airline name
function(a,b){
return a.split("|")[1] > b.split("|")[1]
});
To get it back in the initial format, you could then map. ie:
let i = 0;
s.split(/\"[^\"]+\"/) // regex parses entries
.filter( // removes invalid entries
function(a){
return a.length > 0 && a.indexOf("|") > -1
}).sort( // sorts based on airline name
function(a,b){
return a.split("|")[1] > b.split("|")[1]
}).map( // map puts it back in original state, but ordered
function(z){
return '"'+(i++).toString()+':"' + z;
});
Related
I'm trying to pull out some strings from a website (Pinterest, to be specific), and sort out the strings. The problem is that the strings contain both numbers and text(k for thousands and m for millions).
list.sort(function(a, b) {
var compA = Number( $(a).find('.repinCountSmall').text().trim().replace(/[^0-9]/g, '') );
var compB = Number( $(b).find('.repinCountSmall').text().trim().replace(/[^0-9]/g, '') );
return (compA == compB) ? 0 : (compA > compB) ? -1 : 1;
});
With the above code, if I have .repinCountSmall list function that provides the following:
1
250
999
1k
1.7k
17.3k
1.2m
The problem with the current function is that it strips "k" in 1.7k and arrives at 17. Similarly 17.3k, and 1.2m is treated as 173 and 12 respectively. I want the numbers ending with k multiplied by 1000 first, and string ending with m to be multiplied with 1000000 respectively. The list should sorted after this conversion.
Any solutions? Thanks.
You could use a conversion function something like this (obviously you could add some additional else if statements if you had to allow for multipliers other than "k" and "m"):
function toNumber(s) {
s = s.replace(/[^\dkm.]/g,"");
var u = s.slice(-1);
if (u === "k")
return s.slice(0,-1) * 1000;
else if (u === "m")
return s.slice(0,-1) * 1000000;
return +s;
}
And then reference that from within your .sort() comparator function:
list.sort(function(a,b) {
var n1 = toNumber($(a).find('.repinCountSmall').text());
var n2 = toNumber($(b).find('.repinCountSmall').text());
return n1 - n2;
});
Note also that you don't need nested ternary operators to compare the resulting two numbers: because they are numbers you can just return the result of subtracting one from the other.
How to sort the array of json data having letters and digits?
JS:
function sortOn(property) {
return function (a, b) {
if (a[property] < b[property]) {
return -1;
} else if (a[property] > b[property]) {
return 1;
} else {
return 0;
}
}
}
var data = [{"id":1,name:"text10"},
{"id":4,"name":"text1"}, {"id":4,"name":"text19"}, {"id":4,"name":"text2"}, {"id":4,"name":"text20"},
{"id":5,"name":"book"}];
data.sort(sortOn('name'));
console.log(data);// when I print the JSON getting book,text1,text10..
//But I have to want to show the json as book,text1,text2...
Any one can help me how to sort the name thing having both letters and digits
Please find the jsfiddle for reference.
Very simplistic implementation. Sort on either the number in the name and if it doesn't exist, use the full name. Could be sped up by caching the parseInt || name comparison.
var result = data.sort(function ( a, b ) {
var first = parseInt(/\d+/g.exec(a.name), 10) || a.name,
second = parseInt(/\d+/g.exec(b.name), 10) || b.name;
if (first > second) return 1;
else if (first === second) return 0;
else return -1;
return -1
});
I am trying to organize a observablearray that has inside 2 boolean values and a price. I need via knockout and 2 checkboxes, filter the elements by these two values. Also sort by price ( ascending and descending) the displayed values . I don't put any code because I'm new in knockout and I can't see the way to make these actions.
Appreciate someone who instructed me.
Simple answer, I tried with this, but making some changes on my personal viewModel to supply my needs. So, I make something like this:
self.elementsToShow = ko.pureComputed(function () {
// Represents a filtered and ordered list of elements
var recomend = self.showRecommended(); //chekbox 1
var special = self.showSpecial(); // checkbox2
var sorting = self.currentSortDirection(); //sort direction: price or rating //ascending or descending, represented by an observableArray with that conditions and the //selectedSortDirection
if (!recomend && !special) return self.myOservableArray().sort(function (a, b) {
//in case that no one of the checkboxes where selected but the sort direction was't by default
if (sorting.price != null) {
var fp = sorting.price ? -1 : 1;
ap = parseInt(a.price);
bp = parseInt(b.price);
return ap == bp ? 0 : (fp * (ap < bp ? -1 : 1));
}
else if (sorting.rate != null) {
var f = sorting.rate ? -1 : 1;
ar = parseFloat(a.rating);
br = parseFloat(b.rating);
return ar == br ? 0 : (f * (ar < br ? -1 : 1));
}
});
return ko.utils.arrayFilter(self.myOservableArray(), function (element) {
return (element.recommended != "0" && recomend) || (element.offer != "" && special); //some other conditions for the relection of the checkboxes in the observableArray
}).sort(function (a, b) {
if (sorting.price != null) {
var fs = sorting.price ? -1 : 1;
ap = a.price;
bp = b.price;
return ap == bp ? 0 : (fs * (ap < bp ? -1 : 1));
}
if (sorting.rate != null) {
var fu = sorting.rate ? -1 : 1;
ar = a.rating;
br = b.rating;
return ar == br ? 0 : (fu * (ar < br ? -1 : 1));
}
});
}, self);
I have some objects in an array and want to have them sorted. The objects should be sorted by a metric value. So I have the following function:
objectz.sort(function(a,b){
return b.metric - a.metric;
}
The problem is that some objects have the same property values and the results of the sorting are always different.I want to additionally sort the objects with the same metric value by their name property so I get the same order of objects every time I sort them.
Thx in advance!
objectz.sort(function(a,b){
var result = b.metric - a.metric;
if (!result) return a.name > b.name ? 1 : -1;
return result;
});
Similar to zerkms:
objectz.sort(function(a,b) {
var x = b.metric - a.metric;
return x || b.name - a.name;
});
Seems to be a reverse sort (higher values occur first), is that what you want?
Edit
Note that the - operator is only suitable if the value of 'name' can be converted to a number. Otherwise, use < or >. The sort function should deal with a.name == b.name, which the > opertator on its own won't do, so you need something like:
objectz.sort(function(a,b) {
var x = b.metric - a.metric;
// If b.metric == a.metric
if (!x) {
if (b.name == a.name) {
x = 0;
else if (b.name < a.name) {
x = 1;
else {
x = -1;
}
}
return x;
});
which can be made more concise:
objectz.sort(function(a,b) {
var x = b.metric - a.metric;
if (!x) {
x = (b.name == a.name)? 0 : (b.name < a.name)? 1 : -1;
}
return x;
});
Given that the metric comparison seems to be largest to smallest order, then the ternary exrpession should be:
x = (b.name == a.name)? 0 : (b.name < a.name)? -1 : 1;
if it is required that say Zelda comes before Ann. Also, the value of name should be reduced to all lower case (or all upper case), otherwise 'zelda' and 'Ann' will be sorted in the opposite order to 'Zelda' and 'ann'
My array isn't being sorted properly. Can someone let me know what I am doing wrong?
...
sortArray = new Array ("hello", "Link to Google", "zFile", "aFile");
//sort array
if (dir == "asc") {
sortArray.sort(function(a,b){return a - b});
} else {
sortArray.sort(function(a,b){return b - a});
}
for(var i=0; i<sortArray.length; i++) {
console.log(sortArray[i]);
}
the log is showing them in the same order as they were entered.
You want to make a comparison in your sort, not a subtraction:
if (dir == "asc") {
sortArray.sort(function(a, b) {
a = a.toLowerCase();
b = b.toLowerCase();
return a === b ? 0 : a > b : 1 : -1;
});
} else {
sortArray.sort(function(a, b) {
a = a.toLowerCase();
b = b.toLowerCase();
return b === a ? 0 : b > a : 1 : -1;
});
}
I also used toLowerCase() so that 'Link to Google' is placed appropriately.
EDIT: Updated to fix comparison issue according to comment.
See example →
You're trying to sort by subtracting strings, to which you'll get NaN.
The trouble is that "a - b" is treating the strings like numbers, which returns NaN. You will get the behavior you are looking for (assuming you are looking for case-sensitive sorts) if you replace your sorts with:
if (dir == "asc") {
sortArray.sort(function(a,b){return a < b ? -1 : 1});
} else {
sortArray.sort(function(a,b){return b < a ? -1 : 1});
}
Your comparator functions returns NaN, since it receives two strings, and performs subtraction, an operation that isn't well-defined on strings.
What you should have is something more like:
function(a,b){
return a>b? 1 : (a<b ? -1 : 0);
}
or you can use localeCompare:
function(a,b){
return a.localeCompare(b);
}
Remember to treat case appropriately, e.g. "L" < "a" whilst "l" > "a"