2016-03-30 39 views
2

所以,我認爲編寫幾個Array方法來幫助排序和分組對象將很有趣。這是我的代碼。請原諒log s,這是在推動我的香蕉。您可以在JSBin上運行此代碼,hereArray.find()得到正確的值,但返回錯誤

/** 
* uniquePush method - conditionally add an object to an array 
* 
* Only adds an object if it is not already present on this array. 
* Doesn't do a deep comparison. 
* 
* @param {Object} newElement - the element to check for before pushing 
* @returns {Array} the array, modified if nescessary 
*/ 
Array.prototype.uniquePush = function (newElement) { 
    console.dir(this); 
    var findCount = 0; 

    function findNewElement(element) { 
    console.log("findCount: " + (++findCount)); 
    console.log("Element: " + element); 
    console.log("newElement: " + newElement); 
    var found = (element === newElement); 
    console.log("findNewElement -> " + found); 
    return found; 
    } 

    var foundNewElement = this.find(findNewElement); 
    console.log("this.find(findNewElement): " + foundNewElement) 
    if (foundNewElement) { 
    // Found it. Don't add it. 
    console.log("Declined to add \'" + newElement + "\' to array"); 
    } else { 
    // Didn't find it, go ahead and add it 
    console.log("Adding \'" + newElement + "\' to array"); 
    } 

    console.log("---------------------------------"); 
    return (foundNewElement ? this : this.push(newElement)); 
} 

/** 
* groupBy method - groups an array of objects by property value 
* 
* Returned Array will look like: 
* [ 
* [{prop: "propValue", ...}, {prop: "propValue", ...}], 
* [{prop: "anotherValue", ...}, {prop: "anotherValue", ...}], 
* ... 
* [{prop: "nValue", ...}, {prop: "nValue", ...}] 
* ] 
* 
* @param {String} prop - the property to group by 
* @returns {Array} an Array containing the grouped arrays 
*/ 
Array.prototype.groupBy = function (prop) { 
    // Gather all the possible property values 
    var propValues = []; 
    var entries = this.entries(); 

    var entryValue; 
    while (entryValue = entries.next().value) { 
    propValues.uniquePush(entryValue[1][prop]); 
    } 

    var result = []; 
    for (var i = 0; i < propValues.length; i += 1) { 
    var innerResult = []; 
    this.forEach(function(element) { 
     if (element[prop] === this.propValue) { 
     this.result.push(element); 
     } 
    }, { 
     propValue: propValues[i], 
     result: innerResult 
    }); 
    result.push(innerResult); 
    } 
    return result; 
}; 

var PRODUCTS = [ 
    {category: 'Sporting Goods', price: '$29.99', stocked: true, name: 'Football'}, 
    {category: 'Sporting Goods', price: '$9.99', stocked: true, name: 'Baseball'}, 
    {category: 'Sporting Goods', price: '$29.99', stocked: false, name: 'Basketball'}, 
    {category: 'Electronics', price: '$99.99', stocked: true, name: 'iPod Touch'}, 
    {category: 'Electronics', price: '$399.99', stocked: false, name: 'iPhone 5'}, 
    {category: 'Electronics', price: '$199.99', stocked: true, name: 'Nexus 7'} 
]; 

var groupedByCategory = PRODUCTS.groupBy("category"); 
console.dir(groupedByCategory); 
var groupedByStocked = PRODUCTS.groupBy("stocked"); 
console.dir(groupedByStocked); 

此代碼主要工作正常,但我發現它在布爾值數組上有問題。具體而言,uniquePush()方法使用Array.find()方法來確定給定的newElement是否存在於this陣列中。

但是,它似乎返回了錯誤的值。當我在"stocked"例如運行它,我得到這個:

<edited for brevity> 

[true, false] 
"findCount: 1" 
"Element: true" 
"newElement: true" 
"findNewElement -> true" 
"foundNewElement: true" 
"---------------------------------" 
"Declined to add true to array" 
[true, false] 
"findCount: 1" 
"Element: true" 
"newElement: false" 
"findNewElement -> false" 
"findCount: 2" 
"Element: false" 
"newElement: false" 
"findNewElement -> true" 
"foundNewElement: false" 
"---------------------------------" 
"Adding false to array" 
[true, false, false] 

正如你所看到的,在年底,findNewElement進行評估,以trueArray.find()回報false。有人可以向我解釋爲什麼會發生這種情況嗎?

+0

的indexOf()應,如果你正在尋找所有元素中。 – dandavis

回答

1

Array.find如果沒有找到,則返回undefined。

var foundNewElement = this.find(findNewElement); 
    if (foundNewElement) ... 

如果發現'false',則此檢查失敗。使用if (typeof(foundElement)!='undefined')

+0

如果'newElement === undefined',你不知道你是否找到它。 – Oriol

+0

嗯,我認爲你不能找到一些不確定的東西,邏輯上來說:)我想到了這一點,並認爲它是愚蠢的。而且我有點老派,所以'===未定義',雖然它現在起作用,但它並沒有用於歷史工作,當你在Internet Explorer中可以做undefined = 2時。 –

1

你的代碼是混亂的方式。 以下是您可能會喜歡的簡單解決方案。

Array.prototype.uniquePush = function (newElement) { 
    return this.indexOf(newElement) !== -1 ? this : this.push(newElement); 
} 

https://jsbin.com/nexuboqavo/edit?html,output

+0

這將工作在非索引數組元素上嗎?像說'數組[「一些字符串」]'? – deathgaze

+0

否:) 這是爲簡單的數組。如果你想支持對象,你也可以用Object輕鬆完成。鍵(將返回鍵數組)... – Aleksandrenko

1

我想你是誤會[].find。它用於檢索滿足某些條件的第一個值,而不是檢查某個值是否屬於數組。

如果你想要做的是後者,你可以使用

相關問題