我想為我的 Array 中的每個物件提供一個與 ID 對應的屬性。我已經嘗試了一切可能的方式,下面是最新的。
當我單獨使用 console.log 輸出時,一切看起來都不錯。但是,當我運行 output.push() 然后記錄輸出時,有重復項。
我發現下面的帖子看起來非常相似,但是在應用了建議的更改后,我仍然面臨同樣的問題——因為我在最終輸出中看到重復的 ID。IndexID 屬性不是唯一的,每次迭代都應該是唯一的。
React 物件屬性值在 .push 內回圈中被復制
首先是簡單的例子,然后是實際的代碼示例:
flattenedWorkouts.forEach((currAlias,index) =>{
const obj ={}
const newMemberAttributes = Object.assign(obj, { alias: currAlias });
newMemberAttributes.alias.indexID= index
console.log("memberAttributes:", newMemberAttributes);
output.push(newMemberAttributes.alias)
})
不正確的 FlattenedWorkout 元素的片段......有 100 個所以不包括所有 我已經修剪了物件:
Array [
Object {
"Round": "AMRAP 1",
"indexID": 6,
},
Object {
"Round": "AMRAP 1",
"indexID": 6,
},
Object {
"Round": "AMRAP 1",
"indexID": 6,
},
我希望看到的:
Object {
"Round": "AMRAP 1",
"indexID": 6,
},
Object {
"Round": "AMRAP 1",
"indexID": 7,
},
Object {
"Round": "AMRAP 1",
"indexID": 8,
},
實際問題。下面是起始物件。
var WorkoutDetail = [
//Dummy item to act as begin of carasoul
{
RoundID: 1,
Round: 'AMRAP 1',
NumberOfSets: 3,
Activity: [{
key: '1',
title: 'AMRAP 1',
description: "Banded curtsy lunge to side leg raise",
},
{
key: '2',
title: 'AMRAP 1',
description: "Inchworm with push-up",
},
{
key: '3',
title: 'AMRAP 1',
description: "Static lunge with single arm press",
}
]
},
{
RoundID: 2,
Round: 'AMRAP 2',
NumberOfSets: 2,
Activity: [{
key: '4',
title: 'AMRAP 2',
description: "Side plank to leg extension",
},
{
key: '5',
title: 'AMRAP 2',
description: "Burpee to bench jump",
},
{
key: '6',
title: 'AMRAP 2',
description: "Banded heel tap jump squat",
}
]
},
{
RoundID: 3,
Round: 'AMRAP 3',
NumberOfSets: 1,
Activity: [{
key: '7',
title: 'AMRAP 3',
description: "Weighted pike plank",
},
{
key: '8',
title: 'AMRAP 3',
description: "Incline push up",
},
{ //Dummy item to make as caboose
key: '9',
title: 'AMRAP 3',
description: "Weighted pike plank",
},
//Dummy item to make as caboose in carasoul
]
}
]
// Next a Method I am using to loop over this object and * flatten * it out:
var FlatWorkoutDetail = () => {
var flattenedWorkouts = []
var iterationNumber = 0
//Each Round
WorkoutDetail.forEach(x => {
for (let i = 1; i <= x.NumberOfSets; i ) {
for (let a = 0; a < x.Activity.length; a ) {
var obj = x.Activity[a]
obj.Round = x.Round
obj.SetNumber = i
flattenedWorkouts.push(obj)
iterationNumber ;
}
}
})
return flattenedWorkouts
}
// Simple forEach Solution:
var FlatWorkoutDetailOutput = (val) => {
val.forEach((obj, i) => obj.indexID = i);
}
// Execute the functions:
const TestArray = FlatWorkoutDetail()
const TestArray2 = FlatWorkoutDetailOutput(TestArray)
console.log(TestArray);
最終輸出不正確。6 是起始索引,14 重復兩次:
Array [
Object {
"Round": "AMRAP 1",
"SetNumber": 3,
"description": "Banded curtsy lunge to side leg raise",
"image": null,
"indexID": 6,
"key": "1",
"time": " 45 Seconds",
"title": "AMRAP 1",
"video": "https://boolin-api2.herokuapp.com/fetchImage//Uploads/Game3899-Test.mp4",
},
Object {
"Round": "AMRAP 1",
"SetNumber": 3,
"description": "Inchworm with push-up",
"image": null,
"indexID": 7,
"key": "2",
"time": " 45 Seconds",
"title": "AMRAP 1",
"video": "https://boolin-api2.herokuapp.com/fetchImage//Uploads/Game3899-Workout3.mp4",
},
Object {
"Round": "AMRAP 1",
"SetNumber": 3,
"description": "Static lunge with single arm press",
"image": null,
"indexID": 8,
"key": "3",
"time": " 45 Seconds",
"title": "AMRAP 1",
"video": "https://boolin-api2.herokuapp.com/fetchImage//Uploads/Game3899-Workout4.mp4",
},
Object {
"Round": "AMRAP 1",
"SetNumber": 3,
"description": "Banded curtsy lunge to side leg raise",
"image": null,
"indexID": 6,
"key": "1",
"time": " 45 Seconds",
"title": "AMRAP 1",
"video": "https://boolin-api2.herokuapp.com/fetchImage//Uploads/Game3899-Test.mp4",
},
Object {
"Round": "AMRAP 1",
"SetNumber": 3,
"description": "Inchworm with push-up",
"image": null,
"indexID": 7,
"key": "2",
"time": " 45 Seconds",
"title": "AMRAP 1",
"video": "https://boolin-api2.herokuapp.com/fetchImage//Uploads/Game3899-Workout3.mp4",
},
Object {
"Round": "AMRAP 1",
"SetNumber": 3,
"description": "Static lunge with single arm press",
"image": null,
"indexID": 8,
"key": "3",
"time": " 45 Seconds",
"title": "AMRAP 1",
"video": "https://boolin-api2.herokuapp.com/fetchImage//Uploads/Game3899-Workout4.mp4",
},
Object {
"Round": "AMRAP 1",
"SetNumber": 3,
"description": "Banded curtsy lunge to side leg raise",
"image": null,
"indexID": 6,
"key": "1",
"time": " 45 Seconds",
"title": "AMRAP 1",
"video": "https://boolin-api2.herokuapp.com/fetchImage//Uploads/Game3899-Test.mp4",
},
Object {
"Round": "AMRAP 1",
"SetNumber": 3,
"description": "Inchworm with push-up",
"image": null,
"indexID": 7,
"key": "2",
"time": " 45 Seconds",
"title": "AMRAP 1",
"video": "https://boolin-api2.herokuapp.com/fetchImage//Uploads/Game3899-Workout3.mp4",
},
Object {
"Round": "AMRAP 1",
"SetNumber": 3,
"description": "Static lunge with single arm press",
"image": null,
"indexID": 8,
"key": "3",
"time": " 45 Seconds",
"title": "AMRAP 1",
"video": "https://boolin-api2.herokuapp.com/fetchImage//Uploads/Game3899-Workout4.mp4",
},
Object {
"Round": "AMRAP 2",
"SetNumber": 2,
"description": "Side plank to leg extension",
"image": null,
"indexID": 12,
"key": "4",
"time": " 45 Seconds",
"title": "AMRAP 2",
"video": "https://boolin-api2.herokuapp.com/fetchImage//Uploads/Game3899-Workout4.mp4",
},
Object {
"Round": "AMRAP 2",
"SetNumber": 2,
"description": "Burpee to bench jump",
"image": null,
"indexID": 13,
"key": "5",
"time": " 45 Seconds",
"title": "AMRAP 2",
"video": "https://boolin-api2.herokuapp.com/fetchImage//Uploads/Game3899-Workout4.mp4",
},
Object {
"Round": "AMRAP 2",
"SetNumber": 2,
"description": "Banded heel tap jump squat",
"image": null,
"indexID": 14,
"key": "6",
"time": " 45 Seconds",
"title": "AMRAP 2",
"video": "https://boolin-api2.herokuapp.com/fetchImage//Uploads/Game3899-Workout4.mp4",
},
Object {
"Round": "AMRAP 2",
"SetNumber": 2,
"description": "Side plank to leg extension",
"image": null,
"indexID": 12,
"key": "4",
"time": " 45 Seconds",
"title": "AMRAP 2",
"video": "https://boolin-api2.herokuapp.com/fetchImage//Uploads/Game3899-Workout4.mp4",
},
Object {
"Round": "AMRAP 2",
"SetNumber": 2,
"description": "Burpee to bench jump",
"image": null,
"indexID": 13,
"key": "5",
"time": " 45 Seconds",
"title": "AMRAP 2",
"video": "https://boolin-api2.herokuapp.com/fetchImage//Uploads/Game3899-Workout4.mp4",
},
Object {
"Round": "AMRAP 2",
"SetNumber": 2,
"description": "Banded heel tap jump squat",
"image": null,
"indexID": 14,
"key": "6",
"time": " 45 Seconds",
"title": "AMRAP 2",
"video": "https://boolin-api2.herokuapp.com/fetchImage//Uploads/Game3899-Workout4.mp4",
},
Object {
"Round": "AMRAP 3",
"SetNumber": 1,
"description": "Weighted pike plank",
"image": null,
"indexID": 15,
"key": "7",
"time": " 45 Seconds",
"title": "AMRAP 3",
"video": "https://boolin-api2.herokuapp.com/fetchImage//Uploads/Game3899-Workout4.mp4",
},
Object {
"Round": "AMRAP 3",
"SetNumber": 1,
"description": "Incline push up",
"image": null,
"indexID": 16,
"key": "8",
"time": " 45 Seconds",
"title": "AMRAP 3",
"video": "https://boolin-api2.herokuapp.com/fetchImage//Uploads/Game3899-Workout4.mp4",
},
Object {
"Round": "AMRAP 3",
"SetNumber": 1,
"description": "Weighted pike plank",
"image": null,
"indexID": 17,
"key": "9",
"time": " 45 Seconds",
"title": "AMRAP 3",
"video": "https://boolin-api2.herokuapp.com/fetchImage//Uploads/Game3899-Workout4.mp4",
},
]
uj5u.com熱心網友回復:
我不知道您的代碼中還發生了什么,但是您正在大量改變初始物件。變異是萬惡之源,盡量避免像COVID一樣。
這樣做,它應該可以解決您的索引問題。
var FlatWorkoutDetailOutput = (val) =>{
// shallow copy of the object, it only works cause the object is flat
return val.map((obj, i) => ({...obj, indexID: i}));
}
現在TestArray將具有與以前相同的錯誤,但TestArray2將具有正確的indexID.
根據經驗,每次您希望物件看起來與原來不同時,請根據原始物件創建一個新物件。如果您有一個物件陣列,請使用map并回傳一個包含基于原始物件的新物件的新陣列。
所以在你之前的代碼中而不是這樣做
var obj = x.Activity[a]
obj.Round = x.Round
obj.SetNumber = i
flattenedWorkouts.push(obj)
iterationNumber ;
做這個
var originalObj = x.Activity[a]
var newObj = { ...originalObj } // this is a shallow copy, if you want to copy deep nested objects look up some library
newObj.SetNumber = i
flattenedWorkouts.push(newObj)
iterationNumber ;
uj5u.com熱心網友回復:
發布的代碼無法解釋結果中的重復索引值。
在代碼中:
flattenedWorkouts.forEach((currAlias,index) =>{
flattenedWorkouts沒有示例,因此我將使用:
[{name: 'A'},{name: 'B'},{name: 'C'}];
然后是:
const obj ={}
const newMemberAttributes = Object.assign(obj, { alias: currAlias });
結果是obj和newMemberAttributes參考同一個物件。它與以下相同:
let obj = {alias: currAlias};
let newMemberAttributes = obj;
Object.assign做一個淺拷貝,所以:
newMemberAttributes.alias === currAlias
即傳遞給forEach的原始物件被分配給newMemberAttributes.alias,它的屬性和值不會被復制。對原始物件的任何更改都將反映在newMemberAttributes.alias 中。
后來有:
output.push({ ...obj, alias: currAlias })
輸出未在任何地方定義,所以我添加了let output = []. 由于obj參考與newMemberAttributes相同的物件,因此使用哪個物件并不重要。
obj的解構和別名的合并意味著重復的屬性被覆寫。obj只有兩個屬性:alias和indexID,所以它自己的別名屬性在與currAlias的合并中被覆寫。這幾乎沒有實際影響,因為值無論如何都是相同的(即它們都是對currAlias物件的參考)。
如果你想要做的是一個附加IndexID為屬性的物件flattenedWorkouts,然后就去做:
flattenedWorkouts.forEach((obj, i) => obj.indexID = i);
另一方面,如果您想先復制物件,則在添加indexID之前使用帶有Object.assign 的map復制它們:
let output = flattenedWorkouts.map((obj, i) => Object.assign({}, obj, {indexID: i}));
注意Object.assign是淺拷貝,所以更深的物件是參考,而不是副本。
以下代碼可能會解決問題。或不。
let flattenedWorkouts = [{name: 'A'}, {name: 'B'}, {name: 'C'}];
let output = [];
flattenedWorkouts.forEach((currAlias, index) => {
let obj = {};
let newMemberAttributes = Object.assign(obj, {alias: currAlias});
console.log('obj === newMemberAttributes: ' (obj === newMemberAttributes));
console.log('obj.alias === currAlias : ' (obj.alias === currAlias));
newMemberAttributes.alias.indexID = index;
console.log('iteration ' index ' memberAttributes\n', newMemberAttributes);
output.push({ ...obj, alias: currAlias});
})
console.log('output ' JSON.stringify(output));
如果意圖是跨屬性和值復制并添加indexID屬性,請考慮基于forEach的以下內容(但也請參見下面的地圖示例):
let arr = [{name: 'A'},{name: 'B'},{name: 'C'}];
let result = [];
arr.forEach((obj, i) => {
let newObj = Object.assign({},obj, {indexID: i} );
result.push(newObj);
});
console.log(result);
// Check that original array objects aren't changed
console.log(
'Compare values:\n'
JSON.stringify(arr[0]) '\n'
JSON.stringify(result[0])
);
// Check identity
console.log('arr[0] === result[0] ? ' (arr[0] === result[0]));
使用地圖的示例:
let arr = [{name: 'A'},{name: 'B'},{name: 'C'}];
let output = arr.map((obj, i) => ({...obj, indexID: i}));
console.log(output);
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/400867.html
標籤:javascript 数组 反应原生
上一篇:在二維陣列的情況下查找索引
下一篇:快遞回復范圍
