javascript - JS array sort with regex - Stack Overflow

My objective is to sort an array based on the priority of JS object that uses regular expressions. Here

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, and x and y will be entries from the array, which don't exist on so_UnitKeywordIndicator as properties. So so_UnitKeywordIndicator[x] will always be undefined. – T.J. Crowder Commented Jul 30, 2015 at 18:32
Add a ment  | 

4 Answers 4

Reset to default 4

The 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

相关推荐

  • javascript - JS array sort with regex - Stack Overflow

    My objective is to sort an array based on the priority of JS object that uses regular expressions. Here

    16小时前
    10

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信