My objective is to sort an array based on the priority of JS object that uses regular expressions. Here's what I have:
JS objects defined:
var rx_CondoIndicator = new RegExp(/\bCONDO(MINIUM)?(?!S)/);
var rx_TownhouseIndicator = new RegExp(/\bTOWN\s*(HOUSE|HOME)(?!S)/);
var rx_TimeshareIndicator = new RegExp(/\bTIMESHARE(?!S)/);
Sort objects defined:
var so_UnitKeywordIndicator = {
rx_CondoIndicator: 1,
rx_TownhouseIndicator: 2,
rx_TimeshareIndicator: 3
};
arrUnitNumber = ['TIMESHARE A-1', 'TOWNHOUSE 407', 'CONDO #13']
The following logic ignores the sort object priority and does not sequence the array in the desired order which is "CONDO #13", "TOWNHOUSE 407", "TIMESHARE A-1"
arrUnitNumber.sort(function(x,y){
return so_UnitKeywordIndicator[x] - so_UnitKeywordIndicator[y];
})
Please note that only a fraction of the JS sort objects are shown for brevity.
If this is not the best solution for the problem, I'm open to any suggestions being a novice at JS.
My objective is to sort an array based on the priority of JS object that uses regular expressions. Here's what I have:
JS objects defined:
var rx_CondoIndicator = new RegExp(/\bCONDO(MINIUM)?(?!S)/);
var rx_TownhouseIndicator = new RegExp(/\bTOWN\s*(HOUSE|HOME)(?!S)/);
var rx_TimeshareIndicator = new RegExp(/\bTIMESHARE(?!S)/);
Sort objects defined:
var so_UnitKeywordIndicator = {
rx_CondoIndicator: 1,
rx_TownhouseIndicator: 2,
rx_TimeshareIndicator: 3
};
arrUnitNumber = ['TIMESHARE A-1', 'TOWNHOUSE 407', 'CONDO #13']
The following logic ignores the sort object priority and does not sequence the array in the desired order which is "CONDO #13", "TOWNHOUSE 407", "TIMESHARE A-1"
arrUnitNumber.sort(function(x,y){
return so_UnitKeywordIndicator[x] - so_UnitKeywordIndicator[y];
})
Please note that only a fraction of the JS sort objects are shown for brevity.
If this is not the best solution for the problem, I'm open to any suggestions being a novice at JS.
Share Improve this question edited Jul 30, 2015 at 18:29 T.J. Crowder 1.1m200 gold badges2k silver badges2k bronze badges asked Jul 30, 2015 at 18:25 Gerald DuncanGerald Duncan 231 silver badge3 bronze badges 2- @NRKirby and I have corrected the formatting for you. – T.J. Crowder Commented Jul 30, 2015 at 18:30
-
You're never using your regular expressions for anything in the
sort
loop, andx
andy
will be entries from the array, which don't exist onso_UnitKeywordIndicator
as properties. Soso_UnitKeywordIndicator[x]
will always beundefined
. – T.J. Crowder Commented Jul 30, 2015 at 18:32
4 Answers
Reset to default 4The main problem is that you're never using your regular expressions for anything in the sort
loop, and x
and y
will be entries from the array ('TIMESHARE A-1'
and similar), which don't exist on so_UnitKeywordIndicator
as properties. So so_UnitKeywordIndicator[x]
will always be undefined
.
It looks like you want to use the regular expressions to categorize the strings, and then sort them based on the relatives values in so_UnitKeywordIndicator
. So you'll need to test the strings against the regular expressions.
If you have to start from those strings, I think I'd probably approach it like this (removing so_UnitKeywordIndicator
):
arrUnitNumber.sort(function(x,y){
return getSortingKey(x) - getSortingKey(y);
});
function getSortingKey(value) {
if (rx_CondoIndicator.test(value)) {
return 1;
}
if (rx_TownhouseIndicator.test(value)) {
return 2;
}
if (rx_TimeshareIndicator.test(value)) {
return 3;
}
return 4;
}
Live Example:
var rx_CondoIndicator = /\bCONDO(MINIUM)?(?!S)/;
var rx_TownhouseIndicator = /\bTOWN\s*(HOUSE|HOME)(?!S)/;
var rx_TimeshareIndicator = /\bTIMESHARE(?!S)/;
var arrUnitNumber = ['TIMESHARE A-1', 'TOWNHOUSE 407', 'CONDO #13'];
arrUnitNumber.sort(function(x, y) {
return getSortingKey(x) - getSortingKey(y);
});
arrUnitNumber.forEach(function(entry) {
snippet.log(entry);
});
function getSortingKey(value) {
if (rx_CondoIndicator.test(value)) {
return 1;
}
if (rx_TownhouseIndicator.test(value)) {
return 2;
}
if (rx_TimeshareIndicator.test(value)) {
return 3;
}
return 4;
}
<!-- Script provides the `snippet` object, see http://meta.stackexchange./a/242144/134069 -->
<script src="http://tjcrowder.github.io/simple-snippets-console/snippet.js"></script>
If there are a lot of entries, though, that's inefficient because it has to recalculate the sorting key every time two entries in the array are pared, and so does it repeatedly even for the same value (potentially). So if there are a large number of entries, you're probably best off building an array of objects with the sort key on them instead:
var unitObjects = arrUnitNumber.map(function(entry) {
return {
str: entry,
key: getSortingKey(entry)
};
});
unitObjects.sort(function(x, y){
return x.key - y.key;
});
Then either just use that array, or if you want strings again, just map
at the end:
arrUnitNumber = unitObjects.map(function(entry) {
return entry.str;
});
But again, only if there are a lot (lot) of entries in the array.
Live Example:
var rx_CondoIndicator = /\bCONDO(MINIUM)?(?!S)/;
var rx_TownhouseIndicator = /\bTOWN\s*(HOUSE|HOME)(?!S)/;
var rx_TimeshareIndicator = /\bTIMESHARE(?!S)/;
var arrUnitNumber = ['TIMESHARE A-1', 'TOWNHOUSE 407', 'CONDO #13'];
var unitObjects = arrUnitNumber.map(function(entry) {
return {
str: entry,
key: getSortingKey(entry)
};
});
unitObjects.sort(function(x, y){
return x.key - y.key;
});
unitObjects.forEach(function(entry) {
snippet.log(entry.str);
});
function getSortingKey(value) {
if (rx_CondoIndicator.test(value)) {
return 1;
}
if (rx_TownhouseIndicator.test(value)) {
return 2;
}
if (rx_TimeshareIndicator.test(value)) {
return 3;
}
return 4;
}
<!-- Script provides the `snippet` object, see http://meta.stackexchange./a/242144/134069 -->
<script src="http://tjcrowder.github.io/simple-snippets-console/snippet.js"></script>
Side note: You don't need (or want) the new RegExp(
part where you're defining your regular expressions, JavaScript is unusual in that it has regular expression literals (like string literals); that's what you have in your /.../
:
var rx_CondoIndicator = /\bCONDO(MINIUM)?(?!S)/;
var rx_TownhouseIndicator = /\bTOWN\s*(HOUSE|HOME)(?!S)/;
var rx_TimeshareIndicator = /\bTIMESHARE(?!S)/;
First, put all of your regexes in an array. The order in which they are listed will determine their rank, where the first element is the highest.
var so_UnitKeywordIndicator = [rx_CondoIndicator, rx_TownhouseIndicator, rx_TimeshareIndicator];
Now this function will give the rank for a given unit.
function getSortRank(unit) {
for (var i = 0; i < so_UnitKeywordIndicator.length; i++) {
if (so_UnitKeywordIndicator[i].test(unit)) {
return i;
}
}
return so_UnitKeywordIndicator.length;
}
Finally, you can then use this function to sort your array of units like this:
var sortedUnits = arrUnitNumber.sort(function(x, y) {
return getSortRank(x) - getSortRank(y);
});
just for sharing my problem & solution. I need to order my format data by tag.
const nameTagDatas = ["name(ddd)", "name(ccc)", "name(bbb)", "name(aaa)"];
const tagOrder = ["aaa", "bbb", "ccc", "ddd"];
nameTagDatas.sort(
(a, b) =>
tagOrder.findIndex((e) => a.search(new RegExp("\\(" + e + "\\)")) != -1) -
tagOrder.findIndex((e) => b.search(new RegExp("\\(" + e + "\\)")) != -1)
);
console.log(nameTagDatas) // [ 'name(aaa)', 'name(bbb)', 'name(ccc)', 'name(ddd)' ]
extract function
nameTagDatas.sort(
(a, b) => findIndexByTag(tagOrder, a) - findIndexByTag(tagOrder, b)
);
function findIndexByTag(_orderArr, _searchStr) {
return _orderArr.findIndex(
(e) => _searchStr.search(new RegExp("\\(" + e + "\\)")) != -1
);
}
You can use .match(/<regex>/)
Here is JS
let wordsArr = ['2.World', '1.Hello'];
const regex = /\d/
let answer = wordsArr.sort((a,b) => {
return a.match(regex) - b.match(regex);
});
console.log('answer', answer);
Here is a fiddle.
发布者:admin,转转请注明出处:http://www.yc00.com/questions/1744999606a4605412.html
评论列表(0条)