Javascript排序和订单

时间:2016-04-27 11:43:00

标签: javascript sorting

所以我有这个数组

[ '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]

有人可以帮助我吗?

4 个答案:

答案 0 :(得分:5)

单一提案。

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

为防止这么多替换,我建议您查看sorting with map

答案 1 :(得分:2)

您可以尝试这样的事情:

ALGO:

  1. 根据路径和商店文件名作为值进行分组。
  2. 检查是否存在特殊文件".cfg.js"
  3. 根据自定义排序对以下列表进行排序。
  4. 遍历对象的属性并使用值连接键以再次形成完整路径。
  5. 如果要对完整数组进行排序,可以对键本身进行排序,然后将路径与名称合并。我做到了这一点。如果您不希望这样做,只需从最终循环中删除sort函数。

    示例

    &#13;
    &#13;
    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);
    &#13;
    &#13;
    &#13;

答案 2 :(得分:0)

首先为像hekate&#39;这样的名字制作一个数组。 然后为最终结果制作一个数组。

我们需要3个搜索循环来获取ctrls,cfgs和模块。

如果string包含arrayWithNames [0] +&#39; .module&#39;将整个记录推送到您创建的新数组。与ctrls和cfgs相同。

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

答案 3 :(得分:0)

您可以将自己的比较功能提供给array.sort(请参阅https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort

写一个返回模块,ctrls和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/)。