簡體   English   中英

按鍵值在Javascript中對對象數組進行排序

[英]Sort an array of objects in Javascript by key value

第一次海報,長時間閱讀。 我在排序一系列對象時遇到問題,這是家庭作業,所以我不是要求別人為我編寫代碼,只是指向正確的方向或向我展示我的視線。 對象是在傳入數組和鍵時寫一個函數來對對象數組進行排序,即:

([{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”));

![我在描述錯誤照片的情況下的要求圖片

嗯..這是一個奇怪的。 首先,您需要檢查其中一個密鑰是否為優先級密鑰,並根據該密鑰進行排序。 然后,如果兩個鍵相等,則按值排序。 問題是沒有直接的方法來獲取密鑰,但你可以使用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];
    });
}

我可能已經得到了錯誤的順序,但你明白了。 你甚至需要做這樣的事情真的很奇怪。

這是我的解決方案。 我做了它,所以你也可以添加更多的密鑰並對它們進行排序。

小提琴 - 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));

這是我能想到的最好的。 它將使用給定鍵對所有元素進行排序; 沒有鑰匙的元素將在后面,但它們將處於不可預測的順序。

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;
}

這是一個解決方案,如果數組中的比較對象都沒有傳入比較鍵,則可以猜測該怎么做:

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. 如果兩個比較候選者都沒有所需的屬性,請在對象上找到第一個其他屬性並按其排序。 這是一個猜測因為你沒有真正解釋在這種情況下你想要發生什么,但它適用於你提供的數據示例。

這是一個與上面的版本類似的版本,但是已經擴展為對按字母順序不是傳入屬性的屬性進行排序,並處理空對象(沒有屬性),因此它們在排序結束時進行:

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/

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}]

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM