JS阵列排序与正则表达式

时间:2015-07-30 18:25:19

标签: javascript arrays regex sorting

我的目标是根据使用正则表达式的JS对象的优先级对数组进行排序。这就是我所拥有的:

JS对象定义:

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)/);

对定义的对象进行排序:

var so_UnitKeywordIndicator = {
    rx_CondoIndicator: 1,
    rx_TownhouseIndicator: 2,
    rx_TimeshareIndicator: 3
};

arrUnitNumber = ['TIMESHARE A-1', 'TOWNHOUSE 407', 'CONDO #13'] 

以下逻辑忽略了排序对象的优先级,并且没有按照所需的顺序对数组进行排序,这是#34; CONDO#13"," TOWNHOUSE 407"," TIMESHARE A -1"

arrUnitNumber.sort(function(x,y){
    return so_UnitKeywordIndicator[x] - so_UnitKeywordIndicator[y];
})

请注意,为简洁起见,只显示了一小部分JS排序对象。

如果这不是问题的最佳解决方案,我可以接受任何JS新手的建议。

2 个答案:

答案 0 :(得分:2)

主要问题是,您永远不会在sort循环中使用正则表达式,而xy将是数组中的条目({{ 1}}和类似的),在'TIMESHARE A-1'上不作为属性存在。因此so_UnitKeywordIndicator始终为so_UnitKeywordIndicator[x]

看起来您希望使用正则表达式对字符串进行分类,然后根据undefined中的亲属值对它们进行排序。因此,您需要针对正则表达式测试字符串。

如果 从这些字符串开始,我想我可能会这样做(删除so_UnitKeywordIndicator):

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;
}

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.com/a/242144/134069 -->
<script src="http://tjcrowder.github.io/simple-snippets-console/snippet.js"></script>

然后要么只使用那个数组,要么再次想要字符串,最后只需要var unitObjects = arrUnitNumber.map(function(entry) { return { str: entry, key: getSortingKey(entry) }; }); unitObjects.sort(function(x, y){ return x.key - y.key; });

map

但是,只有当数组中有很多(很多)条目时才会这样。

直播示例:

&#13;
&#13;
arrUnitNumber = unitObjects.map(function(entry) {
    return entry.str;
});
&#13;
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;
}
&#13;
&#13;
&#13;

附注:您不需要(或想要)您正在定义正则表达式的<!-- Script provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 --> <script src="http://tjcrowder.github.io/simple-snippets-console/snippet.js"></script>部分,JavaScript的不寻常之处在于它具有正则表达式文字(像字符串文字);那是你new RegExp(中的内容:

/.../

答案 1 :(得分:0)

首先,将所有正则表达式放在一个数组中。列出它们的顺序将决定它们的排名,其中第一个元素是最高的。

var so_UnitKeywordIndicator = [rx_CondoIndicator, rx_TownhouseIndicator, rx_TimeshareIndicator];

现在这个函数将给出给定单位的等级。

function getSortRank(unit) {
    for (var i = 0; i < so_UnitKeywordIndicator.length; i++) {
        if (so_UnitKeywordIndicator[i].test(unit)) {
            return i;   
        }
    }
    return so_UnitKeywordIndicator.length;
}

最后,您可以使用此函数对您的单位数组进行排序,如下所示:

var sortedUnits = arrUnitNumber.sort(function(x, y) {
    return getSortRank(x) - getSortRank(y);
});