2017-03-24 54 views
0

我想用下面的函數的輸出創建一個對象。寫入循環中的對象

var threads = { 
 
\t "thread1": { 
 
\t \t "upvotes": { 
 
\t \t \t "8fsygfs": true, 
 
\t \t \t "atw9g87": true, 
 
\t \t \t "atw923swg87": true, 
 
\t \t \t "34j2njk": true 
 
\t \t }, 
 
\t \t "downvotes": { 
 
\t \t \t "jne280n": true, 
 
\t \t \t "892ned9": true, 
 
\t \t \t "28hd0ye": true, 
 
\t \t \t "cjsnd09": true, 
 
\t \t \t "02jd0d2": true, 
 
\t \t } 
 
\t }, 
 
\t "thread2": { 
 
\t \t "upvotes": { 
 
\t \t \t "02jd0d2": true, 
 
\t \t \t "8fsygfs": true, 
 
\t \t \t "7dr4229": true, 
 
\t \t \t "232c3f25": true, 
 
\t \t \t "34j2njk": true, 
 
\t \t \t "atw9g87": true, 
 
\t \t \t "atw923swg87": true, 
 
\t \t }, 
 
\t \t "downvotes": { 
 
\t \t \t "jne280n": true, 
 
\t \t \t "9ah8229": true, 
 
\t \t \t "89h208d": true, 
 
\t \t \t "28hd0ye": true, 
 
\t \t \t "cjsnd09": true 
 
\t \t } 
 
\t }, 
 
\t "thread3": { 
 
\t \t "upvotes": { 
 
\t \t \t "02jd0d2": true, 
 
\t \t \t "9ah8229": true, 
 
\t \t \t "838w32l": true, 
 
\t \t \t "78awg2l": true, 
 
\t \t \t "34j2njk": true 
 
\t \t }, 
 
\t \t "downvotes": { 
 
\t \t \t "jne280n": true, 
 
\t \t \t "atw9g87": true, 
 
\t \t \t "892ned9": true, 
 
\t \t \t "28hd0ye": true 
 
\t \t } 
 
\t } 
 
} 
 

 
var members = [ 
 
\t "8fsygfs", 
 
\t "atw9g87", 
 
\t "atw923swg87", 
 
\t "34j2njk", 
 
\t "jne280n", 
 
\t "892ned9", 
 
\t "28hd0ye", 
 
\t "cjsnd09", 
 
\t "02jd0d2", 
 
\t "9ah8229", 
 
\t "9ah8229", 
 
\t "7dr4229", 
 
\t "232c3f25", 
 
\t "838w32l", 
 
\t "78awg2l" 
 
] 
 

 
function getAlignmentSets() { 
 
    var checked = [] 
 
    members.forEach(k => { 
 
\t  members.forEach(l => { 
 
\t \t  var matches = 0 
 
\t \t  if (k != l && (!checked.includes(l))) { 
 
\t \t \t  Object.keys(threads).forEach(m => { 
 
\t \t \t \t  var thread = Object.keys(threads[m].upvotes).concat(Object.keys(threads[m].downvotes)) 
 
\t \t \t \t  if (thread.includes(k) && thread.includes(l)) { 
 
\t \t \t \t \t  matches++ 
 
\t \t \t \t  } 
 
\t \t \t  }) 
 
\t \t \t  console.log(k + ": { " + l + ": " + matches + " }") 
 
\t \t  } 
 
\t  }) 
 
\t  checked.push(k) 
 
    }) 
 
} 
 

 
getAlignmentSets()

此函數計算的時候兩個用戶投票在同一個線程總數 - 不管他們是否投票相同或不同。我需要它輸出的對象,看起來像這樣:

"member1": { 
    "member2": 2, // value is the number of times the this member has 
    "member3": 1, // voted on the same thread as its parent 
    ... 
}, 
"member2": { 
    "member3": 2, 
    ... 
}, 
... 

我與財產支架存取的書面概念寫作的兒童在奮力對象的循環中,更是如此。在此先感謝您的幫助。

+0

我把它改成你的建議。 –

回答

1

假設你的邏輯是正確的,你只是沒有寫入任何返回。我認爲這是coappearances的原因。你缺少這樣的:

if(!coappearances[k]) 
    coappearances[k] = {}; 
coappearances[k][l] = matches; 

下例:

var threads = { 
 
\t "thread1": { 
 
\t \t "upvotes": { 
 
\t \t \t "8fsygfs": true, 
 
\t \t \t "atw9g87": true, 
 
\t \t \t "atw923swg87": true, 
 
\t \t \t "34j2njk": true 
 
\t \t }, 
 
\t \t "downvotes": { 
 
\t \t \t "jne280n": true, 
 
\t \t \t "892ned9": true, 
 
\t \t \t "28hd0ye": true, 
 
\t \t \t "cjsnd09": true, 
 
\t \t \t "02jd0d2": true, 
 
\t \t } 
 
\t }, 
 
\t "thread2": { 
 
\t \t "upvotes": { 
 
\t \t \t "02jd0d2": true, 
 
\t \t \t "8fsygfs": true, 
 
\t \t \t "7dr4229": true, 
 
\t \t \t "232c3f25": true, 
 
\t \t \t "34j2njk": true, 
 
\t \t \t "atw9g87": true, 
 
\t \t \t "atw923swg87": true, 
 
\t \t }, 
 
\t \t "downvotes": { 
 
\t \t \t "jne280n": true, 
 
\t \t \t "9ah8229": true, 
 
\t \t \t "89h208d": true, 
 
\t \t \t "28hd0ye": true, 
 
\t \t \t "cjsnd09": true 
 
\t \t } 
 
\t }, 
 
\t "thread3": { 
 
\t \t "upvotes": { 
 
\t \t \t "02jd0d2": true, 
 
\t \t \t "9ah8229": true, 
 
\t \t \t "838w32l": true, 
 
\t \t \t "78awg2l": true, 
 
\t \t \t "34j2njk": true 
 
\t \t }, 
 
\t \t "downvotes": { 
 
\t \t \t "jne280n": true, 
 
\t \t \t "atw9g87": true, 
 
\t \t \t "892ned9": true, 
 
\t \t \t "28hd0ye": true 
 
\t \t } 
 
\t } 
 
} 
 

 
var members = [ 
 
\t "8fsygfs", 
 
\t "atw9g87", 
 
\t "atw923swg87", 
 
\t "34j2njk", 
 
\t "jne280n", 
 
\t "892ned9", 
 
\t "28hd0ye", 
 
\t "cjsnd09", 
 
\t "02jd0d2", 
 
\t "9ah8229", 
 
\t "9ah8229", 
 
\t "7dr4229", 
 
\t "232c3f25", 
 
\t "838w32l", 
 
\t "78awg2l" 
 
] 
 

 
function getAlignmentSets() { 
 
    var coappearances = {} 
 
    var checked = [] 
 
    members.forEach(k => { 
 
\t  members.forEach(l => { 
 
\t \t  var matches = 0 
 
\t \t  if (k != l && (!checked.includes(l))) { 
 
\t \t \t  Object.keys(threads).forEach(m => { 
 
\t \t \t \t  var thread = Object.keys(threads[m].upvotes).concat(Object.keys(threads[m].downvotes)) 
 
\t \t \t \t  if (thread.includes(k) && thread.includes(l)) { 
 
\t \t \t \t \t  matches++ 
 
\t \t \t \t  } 
 
\t \t \t  }) 
 
\t \t \t  //console.log(k + ": { " + l + ": " + matches + " }") 
 
       if(!coappearances[k]) 
 
        coappearances[k] = {}; 
 
       coappearances[k][l] = matches; 
 
\t \t  } 
 
\t  }) 
 
\t  checked.push(k) 
 
    }) 
 
    return coappearances; 
 
} 
 

 
var result = getAlignmentSets(); 
 
console.log(result);

+0

這就是我所需要的,但它確實揭示了我的邏輯缺陷。我試圖避免兩次檢查對,但它似乎導致了一個意想不到的問題。無論如何,它很容易修復。謝謝。你能不能用括號來表示'coappearances [k] [l]'?這對我來說很奇怪,因爲'coappearances [k]'就是''memberId'',所以'coappearances [k] [l]'似乎應該是''memberId「[l]'或''memberId」' (因爲它只需要第二個訪問者的名字)。 –

1

我知道你已經接受了答案,但希望提供一種替代方法是顯著更使用Set包含每個線程中的唯一成員的高性能:

var threads = { 
 
\t "thread1": { 
 
\t \t "upvotes": { 
 
\t \t \t "8fsygfs": true, 
 
\t \t \t "atw9g87": true, 
 
\t \t \t "atw923swg87": true, 
 
\t \t \t "34j2njk": true 
 
\t \t }, 
 
\t \t "downvotes": { 
 
\t \t \t "jne280n": true, 
 
\t \t \t "892ned9": true, 
 
\t \t \t "28hd0ye": true, 
 
\t \t \t "cjsnd09": true, 
 
\t \t \t "02jd0d2": true, 
 
\t \t } 
 
\t }, 
 
\t "thread2": { 
 
\t \t "upvotes": { 
 
\t \t \t "02jd0d2": true, 
 
\t \t \t "8fsygfs": true, 
 
\t \t \t "7dr4229": true, 
 
\t \t \t "232c3f25": true, 
 
\t \t \t "34j2njk": true, 
 
\t \t \t "atw9g87": true, 
 
\t \t \t "atw923swg87": true, 
 
\t \t }, 
 
\t \t "downvotes": { 
 
\t \t \t "jne280n": true, 
 
\t \t \t "9ah8229": true, 
 
\t \t \t "89h208d": true, 
 
\t \t \t "28hd0ye": true, 
 
\t \t \t "cjsnd09": true 
 
\t \t } 
 
\t }, 
 
\t "thread3": { 
 
\t \t "upvotes": { 
 
\t \t \t "02jd0d2": true, 
 
\t \t \t "9ah8229": true, 
 
\t \t \t "838w32l": true, 
 
\t \t \t "78awg2l": true, 
 
\t \t \t "34j2njk": true 
 
\t \t }, 
 
\t \t "downvotes": { 
 
\t \t \t "jne280n": true, 
 
\t \t \t "atw9g87": true, 
 
\t \t \t "892ned9": true, 
 
\t \t \t "28hd0ye": true 
 
\t \t } 
 
\t } 
 
} 
 

 
var members = [ 
 
\t "8fsygfs", 
 
\t "atw9g87", 
 
\t "atw923swg87", 
 
\t "34j2njk", 
 
\t "jne280n", 
 
\t "892ned9", 
 
\t "28hd0ye", 
 
\t "cjsnd09", 
 
\t "02jd0d2", 
 
\t "9ah8229", 
 
\t "9ah8229", 
 
\t "7dr4229", 
 
\t "232c3f25", 
 
\t "838w32l", 
 
\t "78awg2l" 
 
] 
 

 
function getAlignmentSets() { 
 
    // turn each thread into a Set of participating members 
 
    const threadSets = Object.keys(threads).reduce((prev, thread) => { 
 
     prev[thread] = new Set(
 
     [].concat(Object.keys(threads[thread].upvotes), Object.keys(threads[thread].downvotes)) 
 
    ); 
 
     return prev; 
 
    }, {}); 
 

 
    // on each iteration, check if current user appears in each thread 
 
    // reduce each additional member in the thread to a memberId => voteCount pair 
 
    return members.reduce((memberData, curMember) => { 
 
     memberData[curMember] = {}; 
 
     
 
     Object.keys(threadSets).forEach((set) => { 
 
      const curThread = threadSets[set]; 
 
      if (curThread.has(curMember)) { 
 
       Array.from(curThread.values()).reduce((p, userKey) => { 
 
        if (userKey === curMember) { 
 
         return p; 
 
        } else if (userKey in p) { 
 
         p[userKey] = p[userKey] + 1; 
 
        } else { 
 
         p[userKey] = 1; 
 
        } 
 
        return p; 
 
       }, memberData[curMember]); 
 
      } 
 
     }); 
 
     return memberData; 
 
    }, {}); 
 
} 
 

 
console.log(getAlignmentSets());

您可以在JSPerf檢查出差異:https://jsperf.com/getalignmentset-versions/1

+0

我會保留原來的答案,因爲問題並不要求對函數本身進行評估,但這非常具有啓發性。謝謝。 –

+0

絕對同意第一個答案是對你的問題的更好的答案,應該標記爲這樣。不用擔心,希望它有幫助 –