Sorting an array based on alphabets? - javascript

I need to sort an array based on Alphabets. I have tried sort() method of javascript, but it doesn't work since my array consists of numbers, lowercase letters and uppercase letters. Can anybody please help me out with this? Thanks
For e.g my array is:
[
"#Basil",
"#SuperAdmin",
"#Supreme",
"#Test10",
"#Test3",
"#Test4",
"#Test5",
"#Test6",
"#Test7",
"#Test8",
"#Test9",
"#a",
"#aadfg",
"#abc",
"#abc1",
"#abc2",
"#abc5",
"#abcd",
"#abin",
"#akrant",
"#ankur",
"#arsdarsd",
"#asdd",
"#ashaa",
"#aviral",
"#ayush.kansal",
"#chris",
"#dgji",
"#dheeraj",
"#dsfdsf",
"#dualworld",
"#errry",
"#george",
"#ggh",
"#gjhggjghj"
]

a.sort(function(a, b) {
var textA = a.toUpperCase();
var textB = b.toUpperCase();
return (textA < textB) ? -1 : (textA > textB) ? 1 : 0;
});
This should work (jsFiddle)

function alphabetical(a, b){
var c = a.toLowerCase();
var d = b.toLowerCase();
if (c < d){
return -1;
}else if (c > d){
return 1;
}else{
return 0;
}
}
yourArray.sort(alphabetical);

To sort an array by a key function applied to an element (toUpperCase here), Schwartzian transform, aka "decorate-sort-undecorate" is your technique of choice:
cmp = function(x, y) { return x > y ? 1 : x < y ? -1 : 0 }
sorted = array.map(function(x) {
return [x.toUpperCase(), x]
}).sort(function(x, y) {
return cmp(x[0], y[0])
}).map(function(x) {
return x[1]
})
The major advantage of this approach is that the key function is called exactly once for each element, which can matter when the key is heavy or has side effects.
I realize that you're looking for a simple answer right now, but this might be something for you to consider learning in the future.

Related

How can i sort array in Javascript based on the first characters of the string element of the array ? - javascript

i am this array:
var notifiche_eq= ["10/avdvidv","15/jcbscisb","7/ciudsu"];
and i would this output:
["15/jcbscisb","10/avdvidv","7/ciudsu"]
so based on numeric characters of each element.
I tried this code but doesn't work:
var notifiche_eq= ["10/avdvidv","15/jcbscisb","7/ciudsu"];
notifiche_eq.sort(function(a, b) {
var milliA= notifiche_eq[a].split('/');
var milliB= notifiche_eq[b].split('/');
milliA= (milliA[0])+0;
milliB= (milliB[0])+0;
if(milliB- milliA){
return b-a;
}
});
alert(notifiche_eq);
here there's jsfiddle: https://jsfiddle.net/13tLjqc0/8/
I hope you can help me and sorry for my english :/
You don't need to use notifiche_eq[a]. a is already your item.
I optimized your code, so that it handles >, < and ==
var notifiche_eq= ["10/avdvidv","15/jcbscisb","7/ciudsu"];
notifiche_eq.sort(function(a, b) {
return (+a.split('/')[0] > +b.split('/')[0] ? -1 : (+a.split('/')[0] < +b.split('/')[0] ? 1 : 0));
});
console.log(notifiche_eq);
Version without any ternary operators like asked in the comments :
var notifiche_eq= ["10/avdvidv","15/jcbscisb","7/ciudsu"];
notifiche_eq.sort(function(a, b) {
if(+a.split('/')[0] > +b.split('/')[0]) return -1;
else if(+a.split('/')[0] < +b.split('/')[0]) return 1;
else return 0;
});
console.log(notifiche_eq);
a is already the item of the array, instead of its index so this line is wrong
var milliA= notifiche_eq[a].split('/');
Instead just simply
split the item of the array
get first index value
convert that to number using unary +
i.e.
notifiche_eq.sort(function(a, b) {
return +b.split('/')[0] - +a.split('/')[0];
});
Issues you had...
notifiche_eq[a] and notifiche_eq[b] should be just a and b.
Just return b-a.
var notifiche_eq= ["10/avdvidv","15/jcbscisb","7/ciudsu"];
notifiche_eq = notifiche_eq.sort(function(a, b) {
var milliA= a.split('/');
var milliB= b.split('/');
milliA= +milliA[0];
milliB= +milliB[0];
return milliB - milliA;
});
console.log(notifiche_eq);
You can do some fancy things on your code to make it look good... like..
notifiche_eq.sort((a, b) => +b.split('/')[0] - +a.split('/')[0]);
var notifiche_eq = ["10/avdvidv", "15/jcbscisb", "7/ciudsu"];
// es5
notifiche_eq.sort(function (a, b) {
return b.split('/').shift() - a.split('/').shift()
});
// es6
notifiche_eq.sort((a, b) => b.split('/').shift() - a.split('/').shift());
console.log(notifiche_eq)
Split by /, take the first element and convert it to number by using +
var notifiche_eq= ["10/avdvidv", "15/jcbscisb", "7/ciudsu"];
notifiche_eq.sort((a, b) => +b.split('/')[0] - +a.split('/')[0]);
console.log(notifiche_eq);
You could use a regular expression for getting the starting digits of the string.
var notifiche_eq = ["10/avdvidv","15/jcbscisb","7/ciudsu"];
notifiche_eq.sort(function (a, b) {
function getValue(s) { return s.match(/^\d+/)[0]; }
return getValue(b) - getValue(a);
});
console.log(notifiche_eq);

Why is the browser sorting in the following way

I have following function:
var sortString = function (a, b) {
a = a.toLowerCase();
b = b.toLowerCase();
if (a < b) return 1;
if (a > b) return -1;
return 0;
}
and I have following two strings:
x = ["B1C3N_EUR_DFAK_ALL_3M_ALL","B1C3N_EUR_BPP_BCO_3M"];
When I run the above function on this array. I expect "B1C3N_EUR_BPP_BCO_3M" to be at index 0 whereas browser returns it in the reverse order. I have checked both on Chrome and IE. Why is it so??
Do I need to replace "-" with some other values. Is there any way I can do it without replacing.
You return the wrong value for smaller and greater value in the callback for Array#sort.
if (a < b) return 1;
// ^ should be -1, because a is smaller than b
if (a > b) return -1;
// ^^ should be 1, because a is greater than b
For a more concise style, you could use String#localeCompare, which test the given strings and returns a value in the wanted range.

Sort numbers with slashes in knockout js or javascript

I have series of numbers as strings I want to sort.
for example
4604158/1/7,4604181/1/2,4604158/1/8,4604182/1/2,4604181/1/3, 4604282/1/2 etc.
how can I achieve this with knockout js or even with simple javascript?
I am able to sort only numbers (without slashes) with the following code :
myObservableArray.sort(function (item1, piece2) {
return item1.stringWithSlashes < item2.stringWithSlashes ? -1 : (item1.stringWithSlashes > item2.stringWithSlashes ? 1 : 0);
});
You could split the strings and sort then with the first part, then the second and if equal by the third part.
var array = ['4604158/1/7', '4604181/1/2', '4604158/1/8', '4604182/1/2', '4604181/1/3', '4604282/1/2'];
array.sort(function (a, b) {
var aa = a.split('/'),
bb = b.split('/');
return aa[0] - bb[0] || aa[1] - bb[1] || aa[2] - bb[2];
});
console.log(array);
This is a dynamic way to check with any separator and any length of separated result array.
var array = ['4604158/1/7', '4604181/1/2', '4604158/1/8', '4604182/1/2', '4604181/1/3', '4604282/1/2'];
var separator = '/';
array.sort(function(a, b) {
b = b.split(separator);
return a.split(separator)
.some((v, i) => (+v > +b[i]));
})
console.log(array);

Avoiding repetition using higher order functions in JS?

How to write this snippet more functionality by avoiding repetitions of function creation like this in JavaScript? Just to give a context, I am trying find if the movement from current value to final value has already been achieved.. deltaValue is positive if the movement is towards a higher value and negative if its towards a lower value.
if (deltaValue > 0) {
maxPossibleValue = function(current, final) {
return current > final ? final : current;
}
} else {
maxPossibleValue = function(current, final) {
return current < final ? final : current;
}
}
Assuming there existed < and > as functions, lt and gt in JavaScript, I could have just evaluated this with a single function where predicate is lt and gt dealing with higher order functions. However there are no such functions natively in JS, so is the above method the only way?
maxPossibleValue = function(predicate) {
return function(c, f) {
return predicate(c, f) ? c : f }
}
This can be thought as just templating the required predicate function and returning a new function. I have seen such patterns in Scheme.
#Nina's answer points you in the right direction but Math.max and Math.min are not predicates. And the answer is overly complicated.
I see no reason why the answer should be harder to follow than this
function calculateValue(delta, final, current) {
return (delta > 0 ? Math.min : Math.max)(final, current);
}
calculateValue(-1, 5, 10); // 10
calculateValue(1, 5, 10); // 5
You have already a mechanism for your requirement, Math.min and Math.max.
The code looks like this, but maxPossibleValue is missleading
var maxPossibleValue = function (predicate) {
return function (c, f) {
return predicate(c, f)
}
},
comparer = maxPossibleValue(deltaValue > 0 ? Math.min : Math.max);
Working example:
var deltaValue = -1;
var maxPossibleValue = function (predicate) {
return function (c, f) {
return predicate(c, f)
}
},
comparer = maxPossibleValue(deltaValue > 0 ? Math.min : Math.max);
document.write(comparer(2, 8));

How to sort a collection with price as string in the format "Rs. 350,40"

I have a Javascript array with object containing price as string in the format as follows:
results:[{
image: "http://dummyhost/new3305-82-thumb.jpg",
product_title: "Nokia Lumia 1540",
price: "Rs. 50,790"
},
{
image: "http://dummyhost/new3305-82-thumb.jpg",
product_title: "Nokia Lumia 1520",
price: "Rs. 37,790"
}]
I know we can make use of the following function prototype to sort the value with string or interger:
Array.prototype.sortByProp = function(p){
return this.sort(function(a,b){
return (a[p] > b[p]) ? 1 : (a[p] < b[p]) ? -1 : 0;
});
}
I want the sort to happen for combination of string and integer where we get api response with price specific to country currency format.
You can convert a price in the format "Rs. 50,790" into a number as follows:
p = "Rs. 50,790";
p = +p.replace(/\D/g,"");
That is, do a regular expression replacement to remove all the non-digits from the string (assuming the comma is a thousands separator as mentioned in your comment), then use the unary plus operator to turn the resulting string into a number.
Then you can sort using the numeric values. I'm not sure how you'd want to incorporate that into your generic sortByProp() function though. Perhaps by adding a flag to tell it the property is to be converted into a number:
Array.prototype.sortByProp = function(p,isNumeric){
return this.sort(function(a,b){
a = isNumeric ? +a[p].replace(/\D/g,"") : a[p];
b = isNumeric ? +b[p].replace(/\D/g,"") : b[p];
return (a > b) ? 1 : (a < b) ? -1 : 0;
});
};
results.sortByProp("price", true);
// or for other fields omit the second parameter or pass in false:
results.sortByProp("product_title");
You have to parse the price in a sort method
myArray.sort(function(a, b){
var pA = parseFloat(a["price"].substr(4).replace(",", ""));
var pB = parseFloat(b["price"].substr(4).replace(",", ""));
if (pA < pB) return -1;
if (pA > pB) return 1;
return 0;
});
Edit : good point for the point
How about this:
Array.prototype.sortByProp = function(p){
return this.sort(function(a,b){
console.log(a,b)
return (parseInt(a['price'].substring(4).replace(',','')) > parseInt(b['price'].substring(4).replace(',',''))) ? 1 : 0;
});
}
It takes a substring which starting with position 2 and then replaces , with nothing.
parseInt(a['price'].substring(4).replace(',',''))

Categories