2017-11-22 8 views
0

の前の要素を書き換えます。私はいつもこの問題に悩まされています。新しいオブジェクトを作成し、変数を 'let'変数に割り当てるのではなく 'var'に割り当てようとしたので、問題がどこにあるのか理解できません。ここに私のコードは次のとおりです。任意のヘルプjsが、私はループ内で配列に要素をプッシュしたいが、私のメソッドが値を返した場合、それは常に(おそらく返された値が同じオブジェクトを参照)配列の各要素を書き換えループ

setSeason(competitions, unions) { 
    var categories = this.sortCategories(competitions); 
    var unionsByCategories = new Array(); 
    let k = 0; 
    for (; k < categories.length; k++) { 
     unionsByCategories[k] = this.assignCompetitionsToUnions(unions[0], categories[k]); 
    } 
    this.setState({categories: unionsByCategories, refreshing: false}) 
} 

assignCompetitionsToUnions(unions1, competitions) { 
     var unions2 = this.alignUnions(unions1); 
     let tempUnions = []; 
     for (var i = 0; i < unions2.length; i++) { 
      var tempUnionsCompetitions = new Array(); 
      var tempSubsCompetitions = new Array(); 
      if (Globals.checkNested(unions2[i], 'union')) { 
       tempUnionsCompetitions = unions2[i].union; 
       tempUnionsCompetitions['competitions'] = this.getCompetitionsById(unions2[i].union.id, competitions); 
      } 
      if (Globals.checkNested(unions2[i], 'subs')) { 
       for (var j = 0; j < unions2[i].subs.length; j++) { 
        if (Globals.checkNested(unions2[i].subs[j], 'union')) { 
         tempSubsCompetitions[tempSubsCompetitions.length] = {union: unions2[i].subs[j].union}; 
         tempSubsCompetitions[tempSubsCompetitions.length - 1]['union']['competitions'] = 
          this.getCompetitionsById(unions2[i].subs[j].union.id, competitions) 
        } 
       } 
      } 
      tempUnions.push({union: tempUnionsCompetitions, subs: tempSubsCompetitions}); 
     } 
     return tempUnions; 
    } 

感謝します。

Answer updated by @Knipe要求は常に配列の各要素に書き換える

alignUnions(unions3) { 
    let newUnions = unions3.subs; 
    newUnions = [{union: unions3.union}].concat(newUnions); 
    return newUnions.slice(0, newUnions.length - 1); 
} 

getCompetitionsById(id, competitions) { 
    let tempCompetitions = []; 
    for (let i = 0; i < competitions.length; i++) { 
     if (competitions[i].union.id === id) { 
      tempCompetitions.push(competitions[i]); 
     } 
    } 
    return tempCompetitions; 
} 

sortCategories(competitions) { 
    if (competitions.length === 0) return []; 
    let categories = []; 
    categories.push(competitions.filter((item) => { 
     return item.category === 'ADULTS' && item.sex === 'M' 
    })); 
    categories.push(competitions.filter((item) => { 
     return item.category === 'ADULTS' && item.sex === 'F' 
    })); 
    categories.push(competitions.filter((item) => { 
     return item.category !== 'ADULTS' 
    })); 
    return categories; 
} 

答えて

1

(おそらく戻り値 が同じオブジェクトを参照します)。

おそらく意図していないソース配列の内容を変更しています。配列のコピーを作成することをお勧めします。

これは配列変異の例です。あなたはそのコピー

let array1 = [1,2,3]; 
let array2 = array1.slice(); 
array2[0] = 4; // the content of array1 is still the same [1,2,3] 

を作成することができ、ソース配列に変異を避けるために

let array1 = [1,2,3]; 
let array2 = array1; 
array2[0] = 4; // oops, now the content of array1 is [4,2,3] 

私はいつも「できるようにする新しいオブジェクトを作成し、「VAR」ではない に割り当てることを試みてきました変数。

書き換えから防ぐことはできませんの/ varを聞かせて使用します。 new Array()で新しいオブジェクトを作成しても、書き換えは防止されません。

バグが正確にあなたのコードと説明からここでは読みづらいのですが、あなたは参照によって配列を渡し避け、代わりにコピーを作成し、関数呼び出しにコピーを渡すために試みることができます。

this.assignCompetitionsToUnions(unions[0].slice(), categories[k])

これは浅いコピー例であり、あなたはそれがあなたのケースのために動作させるために、深いコピーを適用する必要がある場合があります。

+2

これは浅いコピーであり、これでは不十分かもしれません。ディープ・コピーの場合は、自己呼び出し関数を使用することができます。単純なオブジェクトと配列とプリミティブで構成されている場合は、JSON.parse(JSON.stringify(myThing))を使用できます。しかし、私は個人的にどのオブジェクトが変更可能であるとみなされるかについての規約を持つことを好みます。 –

+0

この回答は私の好みにはあまりにも理論的です。この特定の状況で何をすべきかは言わない。おそらくKunukn(私のような)は、コードが定義を見ることができない他の関数を呼び出すので、問題がどこにあるのか分からないでしょう。 –

+0

お互いに感謝しています。私は 'this.assignCompetitionsToUnions(unions [0]、categories [k])'の結果を次のように深くコピーしようとしました: 'JSON.parse(JSON.stringify(this.assignCompetitionsToUnions unions [0]、categories [k])));そして今、要素は問題ないので、私はまだ同じオブジェクトを参照していると仮定します。しかし、結果のコピーを作成せずに修正する方法はまだ分かりません。私は使用している他の方法で私の答えを更新します。 – Ondrej11

関連する問題