Javascript排序和排序

Javascript sort and order

本文关键字:排序 Javascript      更新时间:2023-09-26

所以我有这个数组

[ 'vendor/angular/angular.min.js',
  'vendor/angular-nice-bar/dist/js/angular-nice-bar.min.js',
  'vendor/angular-material/modules/js/core/core.min.js',
  'vendor/angular-material/modules/js/backdrop/backdrop.min.js',
  'vendor/angular-material/modules/js/dialog/dialog.min.js',
  'vendor/angular-material/modules/js/button/button.min.js',
  'vendor/angular-material/modules/js/icon/icon.min.js',
  'vendor/angular-material/modules/js/tabs/tabs.min.js',
  'vendor/angular-material/modules/js/content/content.min.js',
  'vendor/angular-material/modules/js/toolbar/toolbar.min.js',
  'vendor/angular-material/modules/js/input/input.min.js',
  'vendor/angular-material/modules/js/divider/divider.min.js',
  'vendor/angular-material/modules/js/menu/menu.min.js',
  'vendor/angular-material/modules/js/select/select.min.js',
  'vendor/angular-material/modules/js/radioButton/radioButton.min.js',
  'vendor/angular-material/modules/js/checkbox/checkbox.min.js',
  'vendor/angular-material/modules/js/switch/switch.min.js',
  'vendor/angular-material/modules/js/tooltip/tooltip.min.js',
  'vendor/angular-material/modules/js/toast/toast.min.js',
  'vendor/angular-clipboard/angular-clipboard.js',
  'vendor/angular-animate/angular-animate.min.js',
  'vendor/angular-aria/angular-aria.min.js',
  'vendor/angular-messages/angular-messages.min.js',
  'vendor/angular-ui-router/release/angular-ui-router.js',
  'src/app/about/about.js',
  'src/app/hekate.cfg.js',
  'src/app/hekate.ctrl.js',
  'src/app/hekate.module.js',
  'src/app/home/home.js',
  'src/app/user/dialog/user.signIn.ctrl.js',
  'src/app/user/dialog/user.signIn.module.js',
  'src/app/user/user.cfg.js',
  'src/app/user/user.ctrl.js',
  'src/app/user/user.module.js',
  'src/common/services/toast.service.js',
  'templates-common.js',
  'templates-app.js'
]

并以上述数组中的以下部分为例:

[ 
  'src/app/hekate.cfg.js',
  'src/app/hekate.ctrl.js',
  'src/app/hekate.module.js',
]

我想像这样排序

[ 
  'src/app/hekate.module.js',
  'src/app/hekate.cfg.js',
  'src/app/hekate.ctrl.js',
]

所以我更具体地想要的是在该数组中找到字符串重复的内容,并在检查末尾是否有 [.cfg.js, .ctrl.js, .module.js] 并自动将它们排序为 [.module.js, .cfg.js, .ctrl.js]

谁能帮我?

单个排序建议。

var array = ['src/app/about/about.js', 'src/app/hekate.cfg.js', 'src/app/hekate.ctrl.js', 'src/app/hekate.module.js', 'src/app/home/home.js', 'src/app/user/dialog/user.signIn.ctrl.js', 'src/app/user/dialog/user.signIn.module.js', 'src/app/user/user.cfg.js', 'src/app/user/user.ctrl.js', 'src/app/user/user.module.js'];
array.sort(function (a, b) {
    function replaceCB(r, a, i) { return r.replace(a, i); }
    var replace = ['.module.js', '.cfg.js', '.ctrl.js'];            
    return replace.reduce(replaceCB, a).localeCompare(replace.reduce(replaceCB, b));
});
document.write('<pre>' + JSON.stringify(array, 0, 4) + '</pre>');

为了防止太多替换,我建议看看用地图排序。

你可以尝试这样的事情:

算法:

  1. 基于路径进行分组,并将文件名存储为值。
  2. 检查是否存在特殊文件".cfg.js"之一
  3. 根据自定义排序对以下列表进行排序。
  4. 循环访问对象的属性并将键与值联接以再次形成完整路径。
如果要对整个数组进行排序,

可以对键本身进行排序,然后将路径与名称合并。我已经做到了。如果您不想这样做,只需从最终循环中删除sort函数即可。

样本

var data=["vendor/angular/angular.min.js","vendor/angular-nice-bar/dist/js/angular-nice-bar.min.js","vendor/angular-material/modules/js/core/core.min.js","vendor/angular-material/modules/js/backdrop/backdrop.min.js","vendor/angular-material/modules/js/dialog/dialog.min.js","vendor/angular-material/modules/js/button/button.min.js","vendor/angular-material/modules/js/icon/icon.min.js","vendor/angular-material/modules/js/tabs/tabs.min.js","vendor/angular-material/modules/js/content/content.min.js","vendor/angular-material/modules/js/toolbar/toolbar.min.js","vendor/angular-material/modules/js/input/input.min.js","vendor/angular-material/modules/js/divider/divider.min.js","vendor/angular-material/modules/js/menu/menu.min.js","vendor/angular-material/modules/js/select/select.min.js","vendor/angular-material/modules/js/radioButton/radioButton.min.js","vendor/angular-material/modules/js/checkbox/checkbox.min.js","vendor/angular-material/modules/js/switch/switch.min.js","vendor/angular-material/modules/js/tooltip/tooltip.min.js","vendor/angular-material/modules/js/toast/toast.min.js","vendor/angular-clipboard/angular-clipboard.js","vendor/angular-animate/angular-animate.min.js","vendor/angular-aria/angular-aria.min.js","vendor/angular-messages/angular-messages.min.js","vendor/angular-ui-router/release/angular-ui-router.js","src/app/about/about.js","src/app/hekate.cfg.js","src/app/hekate.ctrl.js","src/app/hekate.module.js","src/app/home/home.js","src/app/user/dialog/user.signIn.ctrl.js","src/app/user/dialog/user.signIn.module.js","src/app/user/user.cfg.js","src/app/user/user.ctrl.js","src/app/user/user.module.js","src/common/services/toast.service.js","templates-common.js","templates-app.js"];
// Create groups based on path
var o = {};
data.forEach(function(item) {
  var lastIndex = item.lastIndexOf('/') + 1;
  var path = item.substring(0, lastIndex);
  var fname = item.substring(lastIndex);
  if (!o[path]) o[path] = [];
  o[path].push(fname);
});
var manualOrder= [".module.js", ".cfg.js", ".ctrl.js"];
Array.prototype.fuzzyMatch = function(search){
	return this.some(function(item){
  	return item.indexOf(search)>-1;
  });
}
Array.prototype.fuzzySearchIndex = function(search){
	var pos = -1;
  this.forEach(function(item, index){
  	if(search.indexOf(item)>-1){
    	pos = index;
    }
  });
  return pos;
}
function myCustomSort(a,b){
  var a_pos = manualOrder.fuzzySearchIndex(a);
  var b_pos = manualOrder.fuzzySearchIndex(b);
  return a_pos > b_pos ? 1 : a_pos < b_pos ? -1 : 0;
}
// Check for ".cfg.js" and apply custom sort
for (var k in o) {
  if (o[k].fuzzyMatch(".cfg.js")) {
    o[k].sort(myCustomSort);
  }
}
// Merge Path and names to create final value
var final = [];
Object.keys(o).sort().forEach(function(item) {
  if (Array.isArray(o[item])) {
    final = final.concat(o[item].map(function(fn) {
      return item + fn
    }));
  } else
    final = final.concat(o[item]);
});
console.log(final);

首先为像"hekate"这样的名字创建一个数组。然后制作一个数组以获得最终结果。

我们需要 3 个搜索循环来搜索 ctrl、cfg 和模块。

如果字符串包含 arrayWithNames[0] + '.module' 将整个记录推送到您创建的新数组。与 ctrls 和 cfg 相同。

var allItems = []; //your array with all elements
var namesArray = [];
var finalResultsArray = [];
//fill name array here:
for(var i=0; i<=allItems.length; i++){
    //you have to split string and find the module name (like 'hekate'). i hope you know how to split strings
}
//sort by modules, cfgs, ctrls:
for(var i=0; i<=namesArray.length; i++){
    if(allItems[i].indexOf(namesArray[i] + '.module') > -1) {
        finalResultsArray.push(allItems[i]);
    }
}
for(var i=0; i<=namesArray.length; i++){
    if(allItems[i].indexOf(namesArray[i] + '.cfg') > -1) {
        finalResultsArray.push(allItems[i]);
    }
}
for(var i=0; i<=namesArray.length; i++){
    if(allItems[i].indexOf(namesArray[i] + '.ctrl') > -1) {
        finalResultsArray.push(allItems[i]);
    }
}
//now finalResultsArray have what you wanted

你可以为array.sort提供自己的比较函数(见 https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort)

编写一个返回模块、ctrl 和 cfgs 正确顺序的公式:

它应该首先删除后缀,如果其余部分相同,则使用正确的逻辑根据后缀返回顺序。否则,根据字母顺序返回一个值。

更新

我没有测试这段代码(还没有完成),但它应该看起来像这样:

arr.sort(function(a, b) {
  if ((a.endsWith(".cfg.js") || a.endsWith(".ctrl.js") || a.endsWith(".module.js")) &&
    (b.endsWith(".cfg.js") || b.endsWith(".ctrl.js") || b.endsWith(".module.js"))) {
    var sortedSuffixes = {
      ".module.js": 0,
      ".cfg.js": 1,
      ".ctrl.js": 2
    };
    var suffixAIdx = a.lastIndexOf(".cfg.js");
    if (suffixAIdx < 0)  suffixAIdx = a.lastIndexOf(".ctrl.js");
    if (suffixAIdx < 0) suffixAIdx = a.lastIndexOf(".module.js");
    var suffixBIdx = b.lastIndexOf(".cfg.js");
    if (suffixBIdx < 0)  suffixBIdx = b.lastIndexOf(".ctrl.js");
    if (suffixBIdx < 0) suffixBIdx = b.lastIndexOf(".module.js");
    var prefixA = a.substring(0, suffixAIdx);
    var prefixB = b.substring(0, suffixAIdx);
    if (prefixA != prefixB)
    {
        return a.localeCompare(b);
    }
    var suffixA = a.substring(suffixAIdx);
    var suffixB = b.substring(suffixBIdx);
    return sortedSuffixes[suffixA] - sortedSuffixes[suffixB];
  } else {
    return a.localeCompare(b);
  }
});

更新 2

这是一个有效的小提琴(https://jsfiddle.net/d4fmc7ue/)。