按顺序按动态提供的对象属性列表按样式排序对象数组

时间:2017-01-23 14:31:03

标签: javascript arrays sorting

如何在样式顺序中编写泛型排序函数然后通过作为数组提供的属性列表对数组进行排序。



var items = [{ name: "AA" prop1 : 12, prop2: 13, prop3: 5, prop4: 22 },
             { name: "AA" prop1 : 12, prop2: 13, prop3: 6, prop4: 23 },
             { name: "AA" prop1 : 12, prop2: 14, prop3: 5, prop4: 23 },
             { name: "AA" prop1 : 11, prop2: 13, prop3: 5, prop4: 22 },
             { name: "AA" prop1 : 10, prop2: 13, prop3: 9, prop4: 21 }
            ];
// sort by prop1 then by prop3 then by prop4:
var sortedItems = sortByThenBy(items, ["prop1", "prop3", "prop4"]);

// sort by prop1 then by prop3:
var sortedItems = sortByThenBy(items, ["prop1", "prop3"]);




5 个答案:

答案 0 :(得分:1)

使用Array#sortArray#reduce方法执行此操作。

function sortByThenBy(arr, props) {
  // apply custom sort function on array
  return arr.sort(function(a, b) {
    // generate compare function return value by 
    // iterating over the properties array
    return props.reduce(function(bool, k) {
      // if previous compare result is `0` then compare
      // with the next property value and return result
      return bool || (a[k] - b[k]);
      // set initial value as 0
    }, 0);
  })
}

var items = [{
  name: "AA",
  prop1: 12,
  prop2: 13,
  prop3: 5,
  prop4: 22
}, {
  name: "AA",
  prop1: 12,
  prop2: 13,
  prop3: 6,
  prop4: 23
}, {
  name: "AA",
  prop1: 12,
  prop2: 14,
  prop3: 5,
  prop4: 23
}, {
  name: "AA",
  prop1: 11,
  prop2: 13,
  prop3: 5,
  prop4: 22
}, {
  name: "AA",
  prop1: 10,
  prop2: 13,
  prop3: 9,
  prop4: 21
}];

console.log(sortByThenBy(items, ["prop1", "prop3", "prop4"]));

console.log(sortByThenBy(items, ["prop1", "prop3"]));

console.log(sortByThenBy(items, ["prop2", "prop3"]));


function sortByThenBy(arr, props) {
  return arr.sort(function(a, b) {
    return props.reduce(function(bool, k) {
      return bool || (a[k] - b[k]);
    }, 0);
  })
}
.as-console-wrapper {
  max-height: 100% !important;
  top: 0;
}

答案 1 :(得分:1)

您可以迭代密钥并使用Array#some获取订单值。

此提议适用于短路,如果delta是真实的(!== 0),则迭代会中断并且delta会返回到排序回调。

function sortByThenBy(array, keys) {
    return array.sort(function (a, b) {
        var r = 0;
        keys.some(function (k) {
            return r = a[k] - b[k];
        });
        return r;
    });
}

var items = [{ name: "AA", prop1: 12, prop2: 13, prop3: 5, prop4: 22 }, { name: "AA", prop1: 12, prop2: 13, prop3: 6, prop4: 23 }, { name: "AA", prop1: 12, prop2: 14, prop3: 5, prop4: 23 }, { name: "AA", prop1: 11, prop2: 13, prop3: 5, prop4: 22 }, { name: "AA", prop1: 10, prop2: 13, prop3: 9, prop4: 21 }];

console.log(sortByThenBy(items, ["prop1", "prop3", "prop4"]));
console.log(sortByThenBy(items, ["prop1", "prop3"]));
console.log(sortByThenBy(items, ["prop3", "prop1", "prop4"]));
.as-console-wrapper { max-height: 100% !important; top: 0; }

答案 2 :(得分:1)

感谢所有好的答案。有关信息,我发现递归方法也是一种替代解决方案



function sortByThenBy(items, keys) {
    return items.sort(function(it1, it2){return compare(it1, it2, keys);});
}

function compare(it1, it2, keys, index) {
    index = index || 0;
    var currentKey = keys[index];
    return it1[currentKey] < it2[currentKey] ? 1 : (it1[currentKey] > it2[currentKey] ? -1 : compare(it1, it2, keys, index + 1));
} 
&#13;
&#13;
&#13;

答案 3 :(得分:0)

试试这个解决方案。我用data1|0000NumberData2|data3之类的比较创建序列。之后使用本机排序JS函数来比较这个序列。

为避免数字字符串比较问题 - 使用零填充000000345

因此,您可以指定要使用的字段和字段序列。

&#13;
&#13;
var items = [{ name: "AA", prop1 : 12, prop2: 13, prop3: 5, prop4: 22 },
             { name: "AA", prop1 : 2, prop2: 13, prop3: 6, prop4: 23 },
             { name: "AB", prop1 : 12, prop2: 14, prop3: 5, prop4: 23 },
             { name: "AA", prop1 : 11, prop2: 13, prop3: 5, prop4: 22 },
             { name: "AA", prop1 : 10, prop2: 13, prop3: 9, prop4: 21 }];

// sort by prop1 then by prop3 then by prop4:
var sortedItems = sortByThenBy(items, ["prop1", "prop3", "prop4"]);
console.log(sortedItems);

// sort by prop1 then by prop3:
var sortedItems = sortByThenBy(items, ["prop1", "prop3"]);
console.log(sortedItems);

function sortByThenBy(items, props) {
  return items.sort(function(a, b) {
    var a_path = $.map(props, function(item) {
      var ret = a[item];
      return isNumber(ret) ? pad(ret, 10) : ret;
    }).join('|');
    
    var b_path = $.map(props, function(item) {
      var ret = b[item];
      return isNumber(ret) ? pad(ret, 10) : ret;
    }).join('|');
    
    return a_path > b_path ? 1 : (a_path == b_path ? 0 : -1);
  });
}
 
function isNumber(n) {
   return !isNaN(parseFloat(n)) && isFinite(n);
}

function pad(n, width) {
  n = n + '';
  return n.length >= width ? n : new Array(width - n.length + 1).join('0') + n;
}
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
&#13;
&#13;
&#13;

答案 4 :(得分:0)

我认为你可以这样做;

function sortBy(a,p){
  return a.sort(function(a,b){
                  var sp = p.find(k => a[k] - b[k]); // find the property to compare;
                  return a[sp] - b[sp];
                });
}

var items = [{ name: "AA", prop1 : 12, prop2: 13, prop3: 5, prop4: 26 },
             { name: "AA", prop1 : 12, prop2: 13, prop3: 6, prop4: 23 },
             { name: "AA", prop1 : 12, prop2: 14, prop3: 5, prop4: 23 },
             { name: "AA", prop1 : 11, prop2: 13, prop3: 5, prop4: 22 },
             { name: "AA", prop1 : 10, prop2: 13, prop3: 9, prop4: 21 }
            ];
console.log(sortBy(items,["prop1", "prop3", "prop4"]));
console.log(sortBy(items,["prop1", "prop3"]));
console.log(sortBy(items,["prop4", "prop3"]));