2013-10-24 142 views
0

第一次張貼海報,長時間閱讀。我在排序對象數組時遇到了問題,這是作業,所以我不要求某人爲我編寫代碼,只是指向正確的方向或讓我看不見。目的是編寫一個函數在數組中,並通過一鍵即當排序對象的數組:按鍵值對Javascript中的對象數組排序

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

![要求事先知情同意的情況下我描述它錯photo

+1

不好意思,但是關鍵字與排序有什麼關係呢?鑰匙是按照字母順序排列的,還是您傳遞的鑰匙應該是第一位的?所描述的問題還不清楚。 –

+0

對不起,「a」的一個鍵會使a成爲第一個鍵,或者「b」的鍵使b成爲第一個鍵。如使用關鍵字「a」,則返回[{a:1},{a:2},{a:3},{b:1},{b:2},{b:3}]。如果「b」是關鍵字[{b:1},{b:2},{b:3},{a:1},{a:2},{a:3}]將被返回。 –

+0

你的物品有不同的鑰匙。由於您只傳遞''a「',因此只有具有'a:'鍵的對象纔會獲得有意義的排序順序。 – user2736012

回答

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)); 
+0

TypeError:keyOrder.reverse不是函數 \t keyOrder = keyOrder.reverse(); –

+0

@stephenbarker是否傳入一個數組作爲函數的第二個參數? keyOrder應該是一個數組 – sissonb

+0

這是我的錯誤,今晚充滿了學習(記住)。謝謝,從現在起我再看一遍。 –

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

我可能得到的排序順序錯了,但你這個想法。真的很奇怪,你甚至需要做這樣的事情。

+0

+1我喜歡你的成語,以獲得每個對象的關鍵 - 我被困在那個,所以我踢我的答案。 – Barmar

+0

這假定對象將只有一個關鍵。而且,這不提供沒有所需密鑰的對象之間的排序。不清楚OP在這種情況下想做什麼。 – jfriend00

+0

@ jfriend00:這是故意的 - 因此,由於哪個鍵首先由用戶定義(有時b在有時k在c或z之前出現),所以返回0。用戶只指定一個鍵。要指定一個順序,參數必須是一個數組。由於JavaScript的排序是穩定的,如果沒有任何鍵匹配參數,則返回0將確保對象保留先前的順序。因此,用戶可以多次調用該函數,首先按b排序,然後按z排序,然後按m排序。 – slebetman

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

我會接受它,這是最接近螢火蟲的錯誤。所以我就像20%那裏,正確的想法,錯誤的工具hasOwnProperty現在被添加到我的知識謝謝你。 –

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. 如果兩個比較候選人都有所需的屬性,那麼simp按照該財產的價值進行排序。
  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/

0

排序方法的文檔是here。比較功能:

should be a function that accepts two arguments x and y and returns a negative value if x < y, zero if x = y, or a positive value if 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}]