2017-05-03 28 views
2

問題是,當給定多個數組返回一個數組與所有相交的數組值。我已經閱讀了一些解決方案,我正試圖理解這個散列表解決方案。Javascript哈希表數據結構。交叉和減少

我無法理解這行:

a[propName] = a[propName] || {count:0, value: val}; 

據我瞭解,我們通過我們的子陣中的每個元素循環。我們的累加器對象被賦予了子數組值的屬性名稱。

這是我困惑的地方。我們的對象屬性的值是[propName]。我不明白這個價值。我的理解是,我們應該使我們的對象屬性成爲我們子陣列的值(使a[propName]=a[propName]代替a[propName]=propName),但是當我這樣做時,我們無法計算該屬性發生的次數。我不明白爲什麼我們必須將a[propName]以及我們訪問的數據結構與僅使用propName不同。自從我使用a[propName]以後,我們可以統計財產發生的次數。如果有人能夠徹底解釋發生了什麼,我會非常感激。

function intersection(){ 
    // convert arguments to array of arrays 
    var arrays = [].slice.call(arguments); 
    // create an object that tracks counts of instances and is type specific 
    // so numbers and strings would not be counted as same 
    var counts= arrays.reduce(function(a,c){ 
    // iterate sub array and count element instances 
    c.forEach(function(val){ 
     var propName = typeof val + '|' + val; 
     // if array value not previously encountered add a new property   
     a[propName] = a[propName] || {count:0, value: val};  
     // increment count for that property 
     a[propName].count++; 
     console.log(a); 
    }); 
    return a; 
    },{}); 

    // iterate above object to return array of values where count matches total arrays length 
    return Object.keys(counts).reduce(function(resArr, propName){ 
    if(counts[propName].count === arrays.length){ 
     resArr.push(counts[propName].value); 
    } 
    return resArr; 
    },[]); 

} 

回答

1

您指向檢查是否存在a[propName],而且,如果不存在的話(所以它是undefined)線路初始化爲{count:0, value: val};

讓我們仔細看看。

首先,讓我們使用更有意義的名稱。 aaccumulator,您用於跟蹤一切的變量。

開始時,它是一個空的對象。

在第一次迭代c.forEach它沒有任何屬性。

因此,給定像'string | asd'這樣的propName,它會添加它的第一個屬性,而accumulator將變爲accumulator = {'string|asd' : {count:0, value: val}};

然後遞增count的值。

如果發現另一個'string | asd',它只是增加計數,因爲檢查a[propName] = a[propName] || {count:0, value: val};只會保持道具。

let a = {} 
 

 
// a.c does not exist, therefore is undefined 
 
console.log(a.c) 
 

 
a.c = a.b || 1; 
 
// a.c now is 1 
 
console.log(a.c) 
 

 
a.c = a.c || 2; 
 
// a.c is still 1, because the `or` operator returns as soon as it finds a valid value 
 
console.log(a.c)

+2

注意,如果一個'[PROPNAME]'已經存在並且等於0,null,或者別的[ 「falsy」](https://developer.mozilla.org/ en-US/docs/Glossary/Falsy),它也將被替換爲該對象。這可能是很好的,但它不是嚴格的存在檢查。你可以使用'[propName] =(propName in a)|| {count:0,value:val};'如果原文不是所需的行爲。 –

+0

@MikeMcCaughan在本應用程序的上下文中,如果存在'[propName]',它將永遠是一個對象。所以代碼不需要擔心它是一些其他的虛假價值。 – Barmar

+0

@Barmar當然,但是因爲提問者是初學者,所以我覺得值得澄清一點,使用'obj [propName]'檢查是否存在*一般*並不足夠。 –