0

第一次海报,长期读者。我在对一组对象进行排序时遇到问题,这是家庭作业,所以我不是要求有人为我编写代码,只是为我指出正确的方向或向我展示我的视线。对象是在传入数组和键时编写一个函数对对象数组进行排序,即:

([{a:2},{b:2},{a:1},{a:3},{b:3},{b:1}], “a”)

应该返回

[{a:1},{a:2},{a:3},{b:1},{b:2},{b:3}];

我不能使用 underscore.js 或 node.js 之类的东西

    //example array to use
    var testarr = [{a:2},{b:2},{a:1},{a:3},{b:3},{b:1}];
    console.log("array sort test: should look like [{a:1},{a:2},{a:3},{b:1},{b:2},{b:3}]");

    //first attempt 
    var sortArrayByKey = function (arr1, key) {
            (arr1.sort(function(a,b){
            return a[key] - b[key];}));
            return arr1;
    };
    //still only returns testarr
    console.log(sortArrayByKey(testarr, "a") );

    //second attempt
    var sortArrayByKey1 = function (array, key) {
    var compareByKey = function (a, b) {
            var x = a[key]; var y = b[key];
            return x - y;
    }
    array.sort(compareByKey);        
    return array;
    };
    //still only returns testarr
    console.log(sortArrayByKey1(testarr, “a”));

![要求图片,以防我描述错误照片

4

5 回答 5

1

这是我的解决方案。我做到了,因此您还可以添加更多键并对它们进行排序。

小提琴 - http://jsfiddle.net/Q7Q9C/3/

function specialSort(arrayToSort, keyOrder) {
    arrayToSort = arrayToSort.sort(function (a, b) {
        for (var key in keyOrder) {
            if (!keyOrder.hasOwnProperty(key)) {
                continue;
            }
            var aKey = keyOrder[key];
            if (typeof a[aKey] === "undefined" && typeof b[aKey] === "undefined") {
                continue;
            }
            if (typeof a[aKey] !== "undefined" && typeof b[aKey] === "undefined") {
                return -1;
            }
            if (typeof a[aKey] === "undefined" && typeof b[aKey] !== "undefined") {
                return 1;
            }
            if (a[aKey] > b[aKey]) {
                return 1;
            }
            else if (a[aKey] < b[aKey]) {
                return -1;
            }
        }
        return 0;
    });
    return arrayToSort;
}
var arrayToSort = [
    {a:2},
    {b:2},
    {a:1},
    {a:3},
    {b:3},
    {c:3},
    {c:2},
    {b:1}
];
var keyOrder = ["a", "b", "c"];
var sortedArray = specialSort(arrayToSort, keyOrder);
console.log(JSON.stringify(sortedArray));
于 2013-10-24T02:30:36.027 回答
1

嗯..这是一个奇怪的。首先,您需要检查其中一个键是否是优先键并根据该键进行排序。然后,如果两个键相等,则按值排序。问题是没有直接的方法来获取密钥,但您可以使用for .. in循环。

我将假设每个对象只包含一个属性,否则代码将没有意义,因为属性在对象中是无序的:

function sortPreferredKey(arr,key) {
    arr.sort(function(a,b){
        // get the keys of each object
        for (var a_key in a) {break}
        for (var b_key in b) {break}
        if (a_key != b_key) {
            if (a_key == key) return 1;
            else if (b_key == key) return -1;
            else return 0;
        }
        return a[a_key] - b[b_key];
    });
}

我可能弄错了排序顺序,但你明白了。你甚至需要做这样的事情真的很奇怪。

于 2013-10-24T02:19:09.567 回答
0

sort方法的文档在这里。比较功能:

应该是一个函数,它接受两个参数 x 和 y,如果 x < y 返回负值,如果 x = y 返回零,或者如果 x > y 返回正值。

该函数被传递数组中的,所以它就像调用函数:

compareFunction({a:2},{b:2});

您似乎想要做的是首先对属性名称进行排序,然后对值进行排序。这样做的问题是您无法保证返回属性名称的顺序。在这种情况下,如果您对每个对象都有一个自己的属性,您可以这样做

// Return first own property returned by in
// ORDER IS NOT GUARANTEED
function getPropName(o) {
  for (var p in o) {
    if (o.hasOwnProperty(p)) {
      return p;
    }
  }
}

function specialSort(array, key) {
  array.sort(function (a, b) {
    var aProp = getPropName(a);
    var bProp = getPropName(b);
    // If properties are the same, compare value
    if (aProp == bProp) {
      return a[aProp] - b[bProp];
    }

    // Otherwise, compare keys
    return aProp == key? -1 : bProp == key? 1 : aProp.charCodeAt(0) - bProp.charCodeAt(0);
  });
  return array;
}

上面还将对首选键之后的任何其他键(c、d、e 等)进行排序,因此:

var a = [{c:3},{a:2},{b:2},{c:2},{a:1},{a:3},{b:3},{b:1},{c:1}]

specialSort(a, 'b'); // [{b:1}, {b:2}, {b:3}, {a:1}, {a:2}, {a:3}, {c:1}, {c:2}, {c:3}]
于 2013-10-24T02:45:03.003 回答
0

这是一个解决方案,如果数组中被比较的对象都没有传入的比较键,则猜测该怎么做:

var data = [{a:2},{b:2},{a:1},{a:3},{b:3},{b:1}];

function sortByProperty(array, propName) {

    function findFirstProperty(obj) {
        for (x in obj) {
            if (obj.hasOwnProperty(x)) {
                return x;
            }
        }
    }

    return array.sort(function(first, second) {
        var firstHasProp = propName in first;
        var secondHasProp = propName in second;
        if (firstHasProp) {
            if (secondHasProp) {
                // both have the property
                return first[propName] - second[propName];
            } else {
                // only first has the property
                return -1;
            }
        } else if (secondHasProp){
            // only second has the property
            return 1;
        } else {
            // Neither sort candidate has the passed in property name
            // It is not clear what you want to do here as no other property
            //    name has been specified
            return first[findFirstProperty(first)] - second[findFirstProperty(second)]
        }
    });
}

工作演示:http: //jsfiddle.net/jfriend00/PFurT/

从逻辑上讲,它的作用如下:

  1. 如果两个比较候选者都具有所需的属性,则只需按该属性的值进行排序。
  2. 如果只有一个比较候选项具有所需的属性,则将具有所需属性的那个在排序顺序中排在第一位
  3. 如果两个比较候选者都没有所需的属性,则找到对象上的第一个其他属性并按此排序。这是一个猜测,因为您并没有真正解释在这种情况下您想要发生什么,但它适用于您提供的数据示例。

这是一个与上述版本类似的版本,但已扩展为以 alpha 顺序对不是传入属性的属性进行排序,并处理空对象(没有属性),因此它们位于排序的末尾:

var data = [{c:4},{a:2},{b:2},{a:1},{a:3},{b:3},{b:1},{},{c:3}];

function sortByProperty(array, propName) {
    function findFirstProperty(obj) {
        for (x in obj) {
            if (obj.hasOwnProperty(x)) {
                return x;
            }
        }
    }
    return array.sort(function(first, second) {
        var firstHasProp = propName in first;
        var secondHasProp = propName in second;
        if (firstHasProp) {
            if (secondHasProp) {
                // both have the property
                return first[propName] - second[propName];
            } else {
                // only first has the property
                return -1;
            }
        } else if (secondHasProp){
            // only second has the property
            return 1;
        } else {
            // Neither sort candidate has the passed in property name
            // It is not clear what you want to do here as no other property
            //    name has been specified
            var firstProp = findFirstProperty(first);
            var secondProp = findFirstProperty(second);
            if (firstProp === undefined && secondProp === undefined) {
                return 0;
            } else if (firstProp === undefined) {
                return 1;
            } else if (secondProp === undefined) {
                return -1;
            }
            else if (firstProp === secondProp) {
                return first[firstProp] - second[secondProp];
            } else {
                return firstProp.localeCompare(secondProp);
            }
        }
    });
}

工作演示:http: //jsfiddle.net/jfriend00/6QsVv/

于 2013-10-24T02:30:03.713 回答
0

这是我能想到的最好的。它将所有具有给定键的元素排序到前面;没有键的元素将在后面,但它们的顺序是不可预测的。

function sortArrayByKey(arr, key) {
    function compareKey(a, b) {
        if (a.hasOwnProperty(key)) {
            if (b.hasOwnProperty(key)) {
                return a[key] - b[key];
            } else {
                return -1;
            }
        } else if (b.hasOwnProperty(key)) {
            return 1;
        } else {
            return 0;
        }
    }
    arr.sort(compareKey);
    return arr;
}
于 2013-10-24T02:20:24.410 回答