【问题标题】:underscore sortby specify a few items下划线 sortby 指定几个项目
【发布时间】:2018-03-29 13:46:18
【问题描述】:

我正在使用underscores sortBy() 对字符串中的array 进行排序。但是我想比其他字符串更早地对几个(硬编码)字符串进行排序 - 我将向用户显示输出,并且将相关字符串放在前面更自然。

例如:我希望 nametype 分别出现在第一位和第二位,然后按字母顺序排列其他所有内容。

给定:

["above", "name", "below", "foo", "type", "bar"]

我想要:

["name", "type", "above", "bar", "below", "foo"]

我知道我可以向sortBy() 提供iteratee,但我不太清楚如何干净、一致地获得所需的行为。

我试过了:

const relevantSort = function(key) {
    if (key === 'name') { return [0, key]; }
    if (key === 'type') { return [1, key]; }
    return [2, key];
}

(我知道有办法收紧,但这与我的问题是正交的)。

这会产生一个稳定排序、正确排序的数组...但如果我有一堆硬代码并最终在某处返回[10, key],这会崩溃,因为Javascript 数组将强制数字排序为字符串。

是否有一些更清晰、更简洁、更不脆弱的方法来获得我想要的行为?

编辑: 另外,可能从上面看不清楚 - 我事先不知道数组的内容,我不知道nametype 是否会一直存在(如果他们甚至不知道index确实存在)。

【问题讨论】:

    标签: javascript sorting underscore.js


    【解决方案1】:

    怎么样:

    更新

    var array = ["above", "name", "below", "foo", "type", "bar"];
    
    if(array.indexOf('type') > -1) {
        array.splice(1, 0, array.splice(array.indexOf('type'), 1)[0]);
    }
    
    if(array.indexOf('name') > -1) {
        array.splice(0, 0, array.splice(array.indexOf('name'), 1)[0]);
    }
    

    【讨论】:

    • 这会将数组截断为前 2 个元素?我想我会补充一下:我事先不知道这些项目的顺序,而且我并不总是知道nametype会在那里。如果他们确实存在,我只想要他们。
    • 好的,这有点不太清楚,但它会做。顺序无关紧要,即使数组已经排序。
    【解决方案2】:

    我不确定“下划线”是如何工作的,但这个纯 JavaScript 代码可能会帮助您。 这也是一种硬编码,但它可能对你有用。

    var arr = ["above", "name", "below", "foo", "type", "bar"];
    
    ['name', 'type'].concat(arr.filter(function(item) {
        return item !== "name" && item !== "type";
    }).sort(function(a, b) {
        return a > b;
    }));
    

    如果您正在寻找类似["name", "type", 10, 11, 140, "above", "bar", "below", "foo"] 之类的东西,请从排序中删除回调函数,因为它会为您提供先有单词和后有数字的结果。

    【讨论】:

    • 问题是我不总是想将nametype 添加到数组中。但是如果他们在那里,那么我首先想要他们。所以我需要检查它们是否存在,然后将它们过滤掉,然后在开始时添加它们 - 我希望有一些更清洁的东西(尽管我最终将 Schwartzian 变换作为我的解决方案,这有争议的是可读性较差。 ..)
    • 我不确定你对编程的函数概念有多熟悉,但我猜你是因为你使用了下划线,我可以说编程就是转换和处理数据。这可能是您问题的解决方案,只有边缘情况是重复值“名称”和“类型”。 arr.filter(function(item) { return item === "name" || item === "type" }).concat(arr.filter(function(item) { return item !== "name" && item !== "type"; }).sort(function(a, b) { return a > b; }));
    【解决方案3】:

    更新

    var array = ["above", "name", "below", "foo", "type", "bar"]; 
    
    var hardcoded_array = ["name", "type"]; 
    
    var difference = _.difference(array, hardcoded_array); 
    
    var value_exist_array = _.intersection(array, hardcoded_array);
    
    var sorted_array = _.sortBy(difference, function(value) {
           return value; 
    });
    
    console.log(value_exist_array.concat(sorted_array)); // ["name", "type", "above", "bar", "below", "foo"]
    

    【讨论】:

      【解决方案4】:

      您可以将自定义排序函数与指定单词的顺序对象和指定顺序的值一起使用。在排序后的数组中,低值的单词将排在高值的单词之前。

      const order = {'name' : 1, 'type' : 2};
      
      function sortArray(order, arr) {
        return arr.sort(function(a,b) {
          if(order[a] && order[b])
            return order[a] - order[b];
          else if(order[a] || order[b])
            return order[a] || order[b];
          else
            return a.localeCompare(b);   
        });
      }
      
      console.log(sortArray(order, ["above", "name", "below", "foo", "type", "bar"]));
      console.log(sortArray(order, ["above", "below", "foo", "type", "bar"]));
      console.log(sortArray(order, ["above", "below", "foo", "bar"]));
      .as-console-wrapper { max-height: 100% !important; top: 0; }

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-11-30
        相关资源
        最近更新 更多