I'm trying to chain two filters, based in two ranges (arrays) of params that may also be empty, so it would be possible that f.ex. speedlimit=[]
var speedfilter =[240,300]
var pricefilter = [80,120]
var cars = [
{name:'Ferrari', maxspeed:240, price: 100},
{name:'Porsche', maxspeed:220, price: 90},
{name:'Bugatti', maxspeed:300, price: 500}
];
if (speedfilters) {
return cars.filter(function (car) {
return car.maxspeed >= speedfilter[0] && car.maxspeed <= speedfilter[1];
})
} else if (pricefilter) {
return cars.filter(function (car) {
return car.price >= pricefilter[0] && car.price <= pricefilter[1];
})
}
else return cars
The result in the example above should output {name:'Ferrari', speed:240, price: 100}
What would be the way to do it with javascript filter? Thanks in advance!
You could create a filterCar method via prototype inheritance
Array.prototype.filterCar = function(feature, range) {
return this.filter((el) => {
// is the range defined?
if (!!range.length) {
return el[feature] >= range[0] && el[feature] <= range[1];
}
else {
return true;
}
})
};
var cars = [
{name:'Ferrari', speed:240, price: 100},
{name:'Porsche', speed:220, price: 90},
{name:'Bugatti', speed:300, price: 500}
];
var result1 = cars.filterCar('speed', [240, 300])
.filterCar('price', [80, 120]));
var result2 = cars.filterCar('speed', [ ])
.filterCar('price', [80, 120]));
console.log(result1); // [{name: "Ferrari", speed: 240, price: 100}]
console.log(result2); /* [{name: "Ferrari", speed: 240, price: 100},
{name: "Porsche", speed: 220, price: 90}] */
You can wrap your filtering up into a re-usable method, and this can account for the filter not being available.
function filterCars(carsArray, property, rangeArray) {
// if rangeArray is not supplied, or is empty, just return the unfiltered input
if(!rangeArray|| rangeArray.length === 0) {
return carsArray;
}
// otherwise filter according to logic
return carsArray.filter(car => car[property] >= rangeArray[0] && car[property] <= rangeArray[1]);
}
This can be chained, or for more readability called in sequence:
function filterCars(carsArray, property, rangeArray) {
if(!rangeArray|| rangeArray.length === 0) {
return carsArray;
}
return carsArray.filter(car => car[property] >= rangeArray[0] && car[property] <= rangeArray[1]);
}
var speedfilter = []; // [240,300]
var pricefilter = [80,120]
var cars = [
{name:'Ferrari', maxspeed:240, price: 100},
{name:'Porsche', maxspeed:220, price: 90},
{name:'Bugatti', maxspeed:300, price: 500}
];
cars = filterCars(cars,"maxspeed",speedfilter);
cars = filterCars(cars,"price",pricefilter);
console.log(cars);
Related
The code i tried
function findHighest(){
var highest = 0; // assum min 0
var highestItem;
$('tr').each(function(index, item){
if(index > 0){
var math = $(item).find('td').eq(1).text();
var eng = $(item).find('td').eq(2).text();
var lit = $(item).find('td').eq(3).text();
//alert(math)
var sum = parseFloat(math) + parseFloat(eng) + parseFloat(lit)
if (sum > highest){
highest = sum;
highestItem = item;
}
}
})
$(highestItem).css({ 'font-style': 'italic', 'color': 'red' });
}
I am trying to find name of student who got highest marks in class in at least two subjects in JavaScript?
const highestMarks=[];
const studentsWithHighestMarks=[];
const students = [{ name: "mini", subject: [{ maths : 20}, {english: 23}, { science: 25}, { sports: 24}] }, { name: "jerry", subject: [{ maths : 22}, {english: 20}, { science: 20}, { sports: 21}] }, { name: "john", subject: [{ maths : 23}, {english: 25}, { science: 20}, { sports: 21}] }];
students.forEach(student=>{
student.subject.forEach(subject=>{
for(let key in subject){
var index = highestMarks.findIndex(obj => {
return obj.subject === key
});
if (index===-1) {
highestMarks.push({
subject:key,
marks:subject[key],
students:[student.name]
})
}else if(highestMarks[index].marks<subject[key]){
highestMarks[index].marks=subject[key];
highestMarks[index].students=[student.name];
}
else if(highestMarks[index].marks==subject[key]){
highestMarks[index].marks=subject[key];
highestMarks[index].students.push(student.name);
}
}
})
});
students.forEach(student=>{
let count=0;
highestMarks.forEach(item=>{
if(item.students.includes(student.name)){
count++;
}
});
if(count>=2){
studentsWithHighestMarks.push(student.name)
}
})
console.log(studentsWithHighestMarks)
const subjectsConsidering = 2;
const getStudentMarks = (student) => {
const studentMarksList = [];
student.subject.forEach((subjectData) => {
studentMarksList.push(Object.values(subjectData)[0]);
});
const sum = studentMarksList.sort().reverse().reduce((sum, a, index) => {
// restrict only for first 2 subjects
if (index < subjectsConsidering) {
return sum + a;
}
return sum + 0;
});
return sum;
}
students.sort((studentA, studentB) => {
//return 0 for equal marks
return getStudentMarks(studentA) > getStudentMarks(studentB) ? -1 : 1;
});
console.log(students);
//This gives the sorted array of students having the highest marks in at least 2 subjects.
// Transform the data into a more manageable format
// { "subject": [["name", grade], ["name", grade], ["name", grade]] }
let transformed = students.reduce(
(data, student) => {
student.subject.forEach(subject => {
const key = keys(subject)[0];
const grade = [student.name, subject[key]];
if (!(key in data)) {
data[key] = [];
}
data[key].push(grade);
})
return data;
},
{}
)
// Utility function to compare grades
function gradeCompare(a, b) {
return a[1] > b[1] ? -1 : 1;
}
// List the top student in each subject
let names = Object.keys(transformed).map((subject) => {
return transformed[subject].sort(gradeCompare)[0][0];
});
// names :: [ "john", "john", "mini", "mini" ]
// Count the student names
let counts = names.reduce((acc, current) => {
acc[current] = (acc[current] || 0) + 1;
return acc;
}, {});
// counts :: { john: 2, mini: 2 }
// Find the maximum occurring count
let maxCount = Math.max(...Object.values(counts));
// maxCount :: 2
// Filter the keys that have that count
let topStudents = Object.keys(counts).filter(k => counts[k] === maxCount);
// topStudents :: [ "john", "mini" ]
I'm trying to create an array that contains objects with an id and amount, grouped by id. The ids needs to be unique. So if there is 2 objects with same id, the amount will be added.
I can do it with nested for-loops, but I find this solution inelegant and huge. Is there a more efficient or cleaner way of doing it?
var bigArray = [];
// big Array has is the source, it has all the objects
// let's give it 4 sample objects
var object1 = {
id: 1,
amount: 50
}
var object2 = {
id: 2,
amount: 50
}
var object3 = {
id: 1,
amount: 150
}
var object4 = {
id: 2,
amount:100
}
bigArray.push(object1,object2,object3,object4);
// organizedArray is the array that has unique ids with added sum. this is what I'm trying to get
var organizedArray = [];
organizedArray.push(object1);
for(var i = 1; i < bigArray.length; i++ ) {
// a boolean to keep track whether the object was added
var added = false;
for (var j = 0; j < organizedArray.length; j++){
if (organizedArray[j].id === bigArray[i].id) {
organizedArray[j].amount += bigArray[i].amount;
added = true;
}
}
if (!added){
// it has object with new id, push it to the array
organizedArray.push(bigArray[i]);
}
}
console.log(organizedArray);
You can definitly make it cleaner and shorter by using reduce, not sure about efficiency though, i would say a traditional for loop is more efficient :
var bigArray = [];
var object1 = {id: 1, amount: 50}
var object2 = {id: 2, amount: 50}
var object3 = {id: 1, amount: 150}
var object4 = {id: 2, amount: 100}
bigArray.push(object1, object2, object3, object4);
var organizedArray = bigArray.reduce((acc, curr) => {
// check if the object is in the accumulator
const ndx = acc.findIndex(e => e.id === curr.id);
if(ndx > -1) // add the amount if it exists
acc[ndx].amount += curr.amount;
else // push the object to the array if doesn't
acc.push(curr);
return acc;
}, []);
console.log(organizedArray)
Rather than an organized array, how about a single object whose keys are the ids and values are the sums.
var bigArray = [
{ id: 1, amount: 50 },
{ id: 2, amount: 50 },
{ id: 1, amount: 150 },
{ id: 2, amount: 100 }
];
let total = {}
bigArray.forEach(obj => {
total[obj.id] = (total[obj.id] || 0) + obj.amount;
});
console.log(total);
If you really need to convert this to an array of objects then you can map the keys to objects of your choosing like this:
var bigArray = [
{ id: 1, amount: 50 },
{ id: 2, amount: 50 },
{ id: 1, amount: 150 },
{ id: 2, amount: 100 }
];
let total = {}
bigArray.forEach(obj => {
total[obj.id] = (total[obj.id] || 0) + obj.amount;
});
console.log(total);
// If you need the organized array:
let organizedArray = Object.keys(total).map(key => ({ id: key, amount: total[key] }));
console.log(organizedArray);
function getUniqueSums(array) {
const uniqueElements = [];
const arrayLength = array.length;
for(let index = 0; index < arrayLength; index++) {
const element = array[index];
const id = element.id;
const uniqueElement = findElementByPropertyValue(uniqueElements, 'id', id);
if (uniqueElement !== null) {
uniqueElement.amount += element.amount;
continue;
}
uniqueElements.push(element);
}
return uniqueElements;
}
function findElementByPropertyValue(array, property, expectedValue) {
const arrayLength = array.length;
for(let index = 0; index < arrayLength; index++) {
const element = array[index];
const value = element[property];
if (value !== expectedValue) {
continue;
}
return element;
}
return null;
}
This is an untested code. You will be able to understand the logic. Logic is almost same yours. But, perhaps a more readable code.
I have the following array:
var data = [{
length: 900,
fields: 3
},{
length: 1150,
fields: 4
},{
length: 1700,
fields: 5
}];
Now I would like to have a function that returns the fields depending on the given length like:
function getFields(length) {
// return "3" if length <= 900
// return "4" if length <= 1150
// return "5" if length <= 1700
}
How could I achieve this?
As long as data is properly sorted, it is a simple for loop
var data = [{
length: 900,
fields: 3
},{
length: 1150,
fields: 4
},{
length: 1700,
fields: 5
}];
function getFields (value) {
var i;
for (i=0; i<data.length; i++) {
if (value <= data[i].length) return data[i].fields; // exit since we found first match
}
return 0; // what ever the default is for no match
}
console.log(800, getFields(800));
console.log(900, getFields(900));
console.log(1000, getFields(1000));
console.log(1500, getFields(1500));
console.log(2000, getFields(2000));
or with modern array methods you can use find() which is like a for loop code above under the hood:
var data = [{
length: 900,
fields: 3
},{
length: 1150,
fields: 4
},{
length: 1700,
fields: 5
}];
function getFields (value) {
var i;
var match = data.find(function(item) {
return value <= item.length
})
return match ? match.fields : 0;
}
console.log(800, getFields(800));
console.log(900, getFields(900));
console.log(1000, getFields(1000));
console.log(1500, getFields(1500));
console.log(2000, getFields(2000));
Now if the data array is out of order, than it should be sorted.
I'd define it like so:
function getFields(length) {
var d = data
.filter(d => d.length <= length) // get the list of matching objects
.sort((a, b) => b.length - a.length) // sort descending so largest value is at the front of the array
.shift(); // get the first element from the array
return (d !== undefined) ? d.fields : undefined;// if that element exists, return .fields, otherwise undefined
}
In action:
var data = [{
length: 900,
fields: 3
},{
length: 1150,
fields: 4
},{
length: 1700,
fields: 5
}];
function getFields(length) {
var d = data
.filter(d => d.length <= length) // get the list of matching objects
.sort((a, b) => b.length - a.length) // sort descending so largest value is at the front of the array
.shift(); // get the first element from the array
return (d !== undefined) ? d.fields : undefined;// if that element exists, return .fields, otherwise undefined
}
var tests = [1700, 1150, 900, 1000, 1100, 1200, 1300, 1400, 1500, 1600, 1700];
console.log(tests.map(getFields));
While I don't know if this is performant enough for your current use case, but it's relatively readable and easy-to-follow (although this could be made more efficient if the data were always ordered by length, for instance). If you need something more performant, you could do something like this instead:
function getFields(length) {
let d;
let i = data.length - 1;
while (i > -1 && d === undefined) {
if (data[i].length <= length) {
d = data[i].fields;
}
i -= 1;
}
return d;
}
In action:
var data = [{
length: 900,
fields: 3
},{
length: 1150,
fields: 4
},{
length: 1700,
fields: 5
}];
function getFields(length) {
let d;
let i = data.length - 1;
while (i > -1 && d === undefined) {
if (data[i].length <= length) {
d = data[i].fields;
}
i -= 1;
}
return d;
}
var tests = [1700, 1150, 900, 1000, 1100, 1200, 1300, 1400, 1500, 1600, 1700];
console.log(tests.map(getFields));
you can iterate the data and match the conditon
var data = [{
length: 900,
fields: 3
},{
length: 1150,
fields: 4
},{
length: 1700,
fields: 5
}];
function getFields(len) {
var fields = '';
$.each(data, function(key,value) {
if(value.length<=len)
fields = value.fields;
});
return fields;
}
// call function
alert(getFields(1700));
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
You don't need jQuery for this, it can be done with e.g. a standard .find() call. Note that this assumes that the data is sorted by .length as in your example.
var data = [{
length: 900,
fields: 3
}, {
length: 1150,
fields: 4
}, {
length: 1700,
fields: 5
}];
var value = 950;
var matching = data.find(x => value <= x.length);
var fields = matching ? matching.fields : 0;
console.log(fields);
Here is a dummy example. I have an array of objects:
var cars = [
{
name: "Hyundai",
plans: [
{
name: "Something",
add-ons: [
{
cost: 100
},
{
cost: 75
}
]
}, { ... }
]
},
{
name: "Jeep",
plans: [
{
name: "Something",
add-ons: [
{
cost: 50
},
{
cost: 75
}
]
}, { ... }
]
},
{
name: "Buick",
plans: [
{
name: "Something",
add-ons: [
{
cost: 35
},
{
cost: 50
}
]
}, {...}
]
}
]
What I'm trying to do is find the top 2 cars that have the cheapest add-on and reference them via another variable.
Like this:
var top2 = findTopTwo(cars);
findTopTwo(arr) {
return arr.sort(function(a, b) {
// My trouble spot
}).slice(0, 2);
}
With my simple example, the result for top2 would be:
Buick ( cheapest add-on was $35, the value used to compare against )
Jeep ( cheapest add-on was $50, value used to compare against )
So what I would do is feed all of them into an array and then sort it on the cost. That would be my naive approach. The more optimal solution would be to only store 2 objects at a given time instead of a list of all items.
The naive approach would be as simple as:
var items = [];
for ( var i in cars ){
var car = cars[i];
for (var i in car["plans"]){
for (var j = 0; j < car["plans"][i]["add-ons"]){
items.push({"name": car.name, "cost": car["plans"][i]["add-ons"][j]["cost"]});
}
}
}
return items.sort(function(a,b){ return a.cost < b.cost }).slice(0,2);
That will return a list of 2 objects, the object contains the name of the car and the cost. The more effecient thing would be to do something like this:
var biggest = function(arr){
if (arr.length < 2 ) return -1;
return arr[0].cost > arr[1].cost ? 0 : 1;
}
var items = [];
for ( var i in cars ){
var car = cars[i];
for (var i in car["plans"]){
for (var j = 0; j < car["plans"][i]["add-ons"]){
var obj = {"name": car.name, "cost": car["plans"][i]["add-ons"][j]["cost"]};
}
var index = biggest(items)
if (index < 0){
items.push(obj);
}else{
if (items[index].cost > obj.cost)
items[index] = obj;
}
}
}
return items;
this more interesting design will push the first 2 into the list, but then it will find the biggest of the 2 costs and then checks to see if the new one is smaller than it. If the new one is smaller than item[index] it will be replaced.
This will never have the array larger than 2 so it takes up less memory
Another approach. By this approach your original data will not be sorted or modified.
var cars=[{name:"Hyundai",plans:[{name:"Something","add-ons":[{cost:100},{cost:75}]}]},
{name:"Jeep",plans:[{name:"Something","add-ons":[{cost:50},{cost:75}]}]},
{name:"Buick",plans:[{name:"Something","add-ons":[{cost:35},{cost:50}]}]}];
function findTopTwo(cars) {
return cars.map(
car =>
car.plans.reduce(
(prevPlan, plan) =>
plan['add-ons'].reduce((prevAddOn, addOn) => {
if (prevAddOn.cost > addOn.cost) {
prevAddOn.cost = addOn.cost;
}
return prevAddOn;
}, prevPlan), {
cost: Number.MAX_VALUE,
name: car.name
})
)
.sort((a, b) => a.cost - b.cost)
.slice(0, 2)
.map(item => item.name);
}
console.log(findTopTwo(cars));
I had to play around with the object, but here is the gist of it -
var cars = [{
name: "Hyundai",
plans: {
addons: [{
cost: 100
}, {
cost: 75
}]
}
}, {
name: "Jeep",
plans: {
addons: [{
cost: 50
}, {
cost: 75
}]
}
}, {
name: "Buick",
plans: {
addons: [{
cost: 35
}, {
cost: 50
}]
}
}];
var top2 = findTopTwo(cars);
console.log(top2);
function findTopTwo(arr) {
return arr.sort(function (a, b) {
// this map outputs array of costs: [35, 40]
// and Math.min takes the lowest value of each
var a_max_cost = Math.min.apply(null, a.plans.addons.map(function(i){i.cost})),
b_max_cost = Math.min.apply(null, b.plans.addons.map(function(i){i.cost}));
return a_max_cost - b_max_cost;
})
.slice(0, 2);
}
Basically, you need to return a-b in the sort function, where a and b are the lowest addon values. So I calculated the max of both cars on comparison, and used those values to decide which goes where.
Edit: I see you've updated the JS object, the answer should be similar to min, you will only need to figure out which plan to use for a and b. You can do so similar to my use of the Math.max function
One simple way of doing it is to first sort the addons by price (if you don't mind the side effect that addons then remain sorted by price).
function findTopTwo(arr) {
arr.forEach(function (elem) {
elem.plans.addons = elem.plans.addons.sort(function (a, b) {
return a.cost > b.cost;
});
});
return arr.sort(function(a, b) {
return a.plans.addons[0].cost > b.plans.addons[0].cost;
}).slice(0, 2);
}
jsbin example
Using #casraf's data:
const sortedCars = cars.map(car => {
car.plans.addons.sort((a, b) => a.cost - b.cost);
return car;
}).sort((a, b) => {
return a.plans.addons[0].cost - b.plans.addons[0].cost;
});
Line 2 sorts each cars' addons array from low to high. Line 5 sorts the cars from low to high based on the first index of their respective addons property.
If the ES6 syntax is confusing, here's a translation to ES5
I suggest to use sorting with map, then take the top 2 entries and get the data from cars.
var cars = [{ name: "Hyundai", plans: [{ 'add-ons': [{ cost: 100 }, { cost: 75 }] }] }, { name: "Jeep", plans: [{ 'add-ons': [{ cost: 50 }, { cost: 75 }] }] }, { name: "Buick", plans: [{ 'add-ons': [{ cost: 35 }, { cost: 50 }] }] }],
cost = cars.
map(function (a, i) {
return {
index: i,
cost: a.plans.reduce(function (r, b) {
return Math.min(r, b['add-ons'].reduce(function (s, c) {
return Math.min(s, c.cost);
}, Infinity));
}, Infinity)
};
}).
sort(function (a, b) { return a.cost - b.cost; }),
top2 = cost.slice(0, 2).map(function (a) {
return cars[a.index];
});
console.log(top2);
.as-console-wrapper { max-height: 100% !important; top: 0; }
How to implement the following scenario using Javascript only:
Create a car object with properties (top speed, brand, etc.)
Sort a list of cars ordered by those properties
javascript has the sort function which can take another function as parameter - that second function is used to compare two elements.
Example:
cars = [
{
name: "Honda",
speed: 80
},
{
name: "BMW",
speed: 180
},
{
name: "Trabi",
speed: 40
},
{
name: "Ferrari",
speed: 200
}
]
cars.sort(function(a, b) {
return a.speed - b.speed;
})
for(var i in cars)
document.writeln(cars[i].name) // Trabi Honda BMW Ferrari
ok, from your comment i see that you're using the word 'sort' in a wrong sense. In programming "sort" means "put things in a certain order", not "arrange things in groups". The latter is much simpler - this is just how you "sort" things in the real world
make two empty arrays ("boxes")
for each object in your list, check if it matches the criteria
if yes, put it in the first "box"
if no, put it in the second "box"
Example.
This runs on cscript.exe, on windows.
// define the Car class
(function() {
// makeClass - By John Resig (MIT Licensed)
// Allows either new User() or User() to be employed for construction.
function makeClass(){
return function(args){
if ( this instanceof arguments.callee ) {
if ( typeof this.init == "function" )
this.init.apply( this, (args && args.callee) ? args : arguments );
} else
return new arguments.callee( arguments );
};
}
Car = makeClass();
Car.prototype.init = function(make, model, price, topSpeed, weight) {
this.make = make;
this.model = model;
this.price = price;
this.weight = weight;
this.topSpeed = topSpeed;
};
})();
// create a list of cars
var autos = [
new Car("Chevy", "Corvair", 1800, 88, 2900),
new Car("Buick", "LeSabre", 31000, 138, 3700),
new Car("Toyota", "Prius", 24000, 103, 3200),
new Car("Porsche", "911", 92000, 155, 3100),
new Car("Mercedes", "E500", 67000, 145, 3800),
new Car("VW", "Passat", 31000, 135, 3700)
];
// a list of sorting functions
var sorters = {
byWeight : function(a,b) {
return (a.weight - b.weight);
},
bySpeed : function(a,b) {
return (a.topSpeed - b.topSpeed);
},
byPrice : function(a,b) {
return (a.price - b.price);
},
byModelName : function(a,b) {
return ((a.model < b.model) ? -1 : ((a.model > b.model) ? 1 : 0));
},
byMake : function(a,b) {
return ((a.make < b.make) ? -1 : ((a.make > b.make) ? 1 : 0));
}
};
function say(s) {WScript.Echo(s);}
function show(title)
{
say ("sorted by: "+title);
for (var i=0; i < autos.length; i++) {
say(" " + autos[i].model);
}
say(" ");
}
autos.sort(sorters.byWeight);
show("Weight");
autos.sort(sorters.byModelName);
show("Name");
autos.sort(sorters.byPrice);
show("Price");
You can also make a general sorter.
var byProperty = function(prop) {
return function(a,b) {
if (typeof a[prop] == "number") {
return (a[prop] - b[prop]);
} else {
return ((a[prop] < b[prop]) ? -1 : ((a[prop] > b[prop]) ? 1 : 0));
}
};
};
autos.sort(byProperty("topSpeed"));
show("Top Speed");
I have wrote this simple function for myself:
function sortObj(list, key) {
function compare(a, b) {
a = a[key];
b = b[key];
var type = (typeof(a) === 'string' ||
typeof(b) === 'string') ? 'string' : 'number';
var result;
if (type === 'string') result = a.localeCompare(b);
else result = a - b;
return result;
}
return list.sort(compare);
}
for example you have list of cars:
var cars= [{brand: 'audi', speed: 240}, {brand: 'fiat', speed: 190}];
var carsSortedByBrand = sortObj(cars, 'brand');
var carsSortedBySpeed = sortObj(cars, 'speed');
Here's a short example, that creates and array of objects, and sorts numerically or alphabetically:
// Create Objects Array
var arrayCarObjects = [
{brand: "Honda", topSpeed: 45},
{brand: "Ford", topSpeed: 6},
{brand: "Toyota", topSpeed: 240},
{brand: "Chevrolet", topSpeed: 120},
{brand: "Ferrari", topSpeed: 1000}
];
// Sort Objects Numerically
arrayCarObjects.sort((a, b) => (a.topSpeed - b.topSpeed));
// Sort Objects Alphabetically
arrayCarObjects.sort((a, b) => (a.brand > b.brand) ? 1 : -1);
Let us say we have to sort a list of objects in ascending order based on a particular property, in this example lets say we have to sort based on the "name" property, then below is the required code :
var list_Objects = [{"name"="Bob"},{"name"="Jay"},{"name"="Abhi"}];
Console.log(list_Objects); //[{"name"="Bob"},{"name"="Jay"},{"name"="Abhi"}]
list_Objects.sort(function(a,b){
return a["name"].localeCompare(b["name"]);
});
Console.log(list_Objects); //[{"name"="Abhi"},{"name"="Bob"},{"name"="Jay"}]
With ES6 arrow functions it will be like this:
//Let's say we have these cars
let cars = [ { brand: 'Porsche', top_speed: 260 },
{ brand: 'Benz', top_speed: 110 },
{ brand: 'Fiat', top_speed: 90 },
{ brand: 'Aston Martin', top_speed: 70 } ]
Array.prototype.sort() can accept a comparator function (here I used arrow notation, but ordinary functions work the same):
let sortedByBrand = [...cars].sort((first, second) => first.brand > second.brand)
// [ { brand: 'Aston Martin', top_speed: 70 },
// { brand: 'Benz', top_speed: 110 },
// { brand: 'Fiat', top_speed: 90 },
// { brand: 'Porsche', top_speed: 260 } ]
The above approach copies the contents of cars array into a new one and sorts it alphabetically based on brand names. Similarly, you can pass a different function:
let sortedBySpeed =[...cars].sort((first, second) => first.top_speed > second.top_speed)
//[ { brand: 'Aston Martin', top_speed: 70 },
// { brand: 'Fiat', top_speed: 90 },
// { brand: 'Benz', top_speed: 110 },
// { brand: 'Porsche', top_speed: 260 } ]
If you don't mind mutating the orginal array cars.sort(comparatorFunction) will do the trick.
A version of Cheeso solution with reverse sorting, I also removed the ternary expressions for lack of clarity (but this is personal taste).
function(prop, reverse) {
return function(a, b) {
if (typeof a[prop] === 'number') {
return (a[prop] - b[prop]);
}
if (a[prop] < b[prop]) {
return reverse ? 1 : -1;
}
if (a[prop] > b[prop]) {
return reverse ? -1 : 1;
}
return 0;
};
};