2016-02-18 90 views
1

我有一個函數用於處理和創建一個對象數組,併爲數組中的每個項添加一個position鍵,但它似乎無法正常工作。 。當返回數組時,對象數組的對象屬性發生變化

My功能:

var fillQueue = function(choices, currentQueue) { 
    var choice, i, positionInQueue, previousTitle, resultQueue; 

    resultQueue = []; 
    previousTitle = ""; 

    i = 0; 

    while (i < 10) { 
    positionInQueue = i + 1; 
    console.log('Adding song to position ' + positionInQueue); 

    if (currentQueue[i]) { 
     previousTitle = currentQueue[i].title; 
     currentQueue[i].position = positionInQueue; 
     resultQueue.push(currentQueue[i]); 
    } else { 
     choice = choices[Math.floor(Math.random() * choices.length)]; 

     if (choice.title !== previousTitle) { 
     previousTitle = choice.title; 
     choice.position = positionInQueue; 
     resultQueue.push(choice); 
     } else { 
     choice = choices[Math.floor(Math.random() * choices.length)]; 
     previousTitle = choice.title; 
     choice.position = positionInQueue; 
     resultQueue.push(choice); 
     } 
    } 

    i++; 
    } 

    return resultQueue; 
}; 

如果這是正確調用,在值代替choicescurrentQueuecurrentQueue也可以是一個空數組)象下面,則該函數返回一個數組,這是意,但由於某種原因,螺絲釘上的每個物體上都有position鍵。

var test = fillQueue([ {title: '1'}, {title: '2'}, {title: '3'}, {title: '4'} ], [ { title: '5', position: 1 } ]); 

上述變量包含此:

[ { title: '5', position: 1 }, 
    { title: '1', position: 9 }, 
    { title: '3', position: 7 }, 
    { title: '1', position: 9 }, 
    { title: '2', position: 10 }, 
    { title: '2', position: 10 }, 
    { title: '3', position: 7 }, 
    { title: '1', position: 9 }, 
    { title: '1', position: 9 }, 
    { title: '2', position: 10 } ] 

正如你所看到的,這不是正確到每個對象添加position秒。返回數組中的每個對象應具有position,i + 1,但相反它似乎是從1到10的一些隨機數 - 某些對象甚至具有相同的position

我曾嘗試:

  • 重命名position別的東西,如果那件事,已經正在使用的JavaScript
  • 確保正確position被添加到對象之前並在.push之後加入到數組中。

這讓我很困惑。您的幫助將不勝感激。

小提琴:https://jsfiddle.net/deansheather/jnw8jdf4/

+0

什麼是您需要的輸出格式? –

+1

你推入數組的是**參數**到* choice *,所以每次更新'choice.position'時,該選項的所有實例都會獲得相同的「位置」值,例如, 「標題:1」的所有選擇將具有相同的位置,因爲它們都引用同一個對象。您需要創建選擇副本,更新其位置並將副本推送到數組中。 – RobG

+0

@TajAhmed我正在尋找一個包含10個對象的數組。此數組中的每個對象**必須**具有等於「i + 1」的「位置」屬性。 – deansheather

回答

1

你是推引用到陣列,所以每次更新choice.position陣列中的所有相同的選擇引用得到相同的位置值。

要修復該問題,請複製選項對象,更新其位置並將其推入數組中,例如,

if (choice.title !== previousTitle) { 
     previousTitle = choice.title; 
     newChoice = objCopyShallow(choice); // see below for copy function 
     newChoice.position = positionInQueue; 
     resultQueue.push(newChoice); 
} 

對於這種應用,簡單的複製功能:

function objCopyShallow(obj) { 
    return Object.keys(obj).reduce(function(acc, v) { 
     acc[v] = obj[v]; 
     return acc; 
    },{}); 
} 

這裏有100萬個的問題和答案關於「如何複製一個對象」,如果你想更深層次的東西。

0

我能想出以下。這是因爲我避免使用for/while循環,在JS中引用「gotchas」時,需要注意何時使用它更新值。

var fillQueue = function(choices, currentQueue) { 
 
    // concat choices to end of currentQueue 
 
    // create a new array instance with updated position property using .map 
 
    // keep 10 elements from new array starting at index 0 
 
    return currentQueue.concat(choices).map((e, i) => { 
 
    return Object.assign({title:e.title, position:i+1}); 
 
    }).splice(0, 10) 
 
};

+0

這與OP有相同的問題。 – RobG

1

由於RobG已經表示您正在推送對您的數組的引用。所以創建您的選擇對象的副本,然後推送到您的數組。使用clone() 創建對象的副本將您的任務更改爲 choice = clone(choices[Math.floor(Math.random() * choices.length)]); 您完成了。

function clone(obj) { 
    if (null == obj || "object" != typeof obj) return obj; 
    var copy = obj.constructor(); 
    for (var attr in obj) { 
     if (obj.hasOwnProperty(attr)) copy[attr] = obj[attr]; 
    } 
    return copy; 
} 
相關問題