在一行代码中用扩展语法替换数组条目?
Replace array entry with spread syntax in one line of code?
我正在使用 ... 展开语法替换反应状态数组中的项目。这有效:
let newImages = [...this.state.images]
newImages[4] = updatedImage
this.setState({images:newImages})
是否可以在一行代码中做到这一点?是这样的吗? (这显然行不通...)
this.setState({images: [...this.state.images, [4]:updatedImage})
Object.assign
完成任务:
this.setState({images: Object.assign([], this.state.images, {4: updatedImage}));
...但涉及一个临时对象(最后一个)。尽管如此,只有一个临时对象......如果你用 slice
这样做并展开数组,它会涉及更多的临时对象([=15= 中的两个数组,它们的迭代器,结果对象通过调用迭代器的 next
函数 [在 ...
句柄内] 等创建。
之所以有效,是因为 normal JS arrays aren't really arrays1 (this is subject to optimization, of course), they're objects with some special features. Their "indexes" are actually property names meeting certain criteria2。所以在那里,我们将 this.state.images
分散到一个新数组中,将其作为目标传递到 Object.assign
中,并给 Object.assign
一个对象 属性 命名为 "4"
(是的,它最终是一个字符串,但我们可以将它写成一个数字)我们想要更新的值。
实例:
const a = [0, 1, 2, 3, 4, 5, 6, 7];
const b = Object.assign([], a, {4: "four"});
console.log(b);
如果4
可以是可变的,没关系,你可以使用computed property name(ES2015中的新功能):
let n = 4;
this.setState({images: Object.assign([], this.state.images, {[n]: updatedImage}));
注意 n
周围的 []
。
实例:
const a = [0, 1, 2, 3, 4, 5, 6, 7];
const index = 4;
const b = Object.assign([], a, {[index]: "four"});
console.log(b);
1 披露:那是我贫血的小博客上的 post。
2 是项目符号列表后的第二段:
An integer index is a String-valued property key that is a canonical numeric String (see 7.1.16) and whose numeric value is either +0 or a positive integer ≤ 253-1. An array index is an integer index whose numeric value i is in the range +0 ≤ i < 232-1.
因此 Object.assign
与创建数组然后更新索引 4 的操作相同。
您可以使用地图:
const newImages = this.state.images
.map((image, index) => index === 4 ? updatedImage : image)
this.setState({images: [...this.state.images.slice(0, 4), updatedImage, ...this.state.images.slice(5)]})
修改原作post:更改了切片方法第二个参数中的 3 o a 4 因为第二个参数指向数组中超出最后一个保留的成员,它现在正确回答原题。
这是我的自我解释非一行
const wantedIndex = 4;
const oldArray = state.posts; // example
const updated = {
...oldArray[wantedIndex],
read: !oldArray[wantedIndex].read // attributes to change...
}
const before = oldArray.slice(0, wantedIndex);
const after = oldArray.slice(wantedIndex + 1);
const menu = [
...before,
updated,
...after
]
我参考了@Bardia Rastin 的解决方案,我发现该解决方案在索引值处有错误(它替换了索引 3 而不是 4 处的项目)。
如果要替换有索引值index的item,答案应该是
this.setState({images: [...this.state.images.slice(0, index), updatedImage, ...this.state.images.slice(index + 1)]})
this.state.images.slice(0, index)
是一个新数组,项目从 从 0 到索引 - 1(不包括索引)
this.state.images.slice(index)
是一个新数组,其项目从 index 开始,然后是 .
要正确替换索引 4 处的项目,答案应为:
this.setState({images: [...this.state.images.slice(0, 4), updatedImage, ...this.state.images.slice(5)]})
您可以将数组转换为对象 (...array1
),替换项目 ([1]:"seven"
),然后将其转换回数组 (Object.values
) :
array1 = ["one", "two", "three"];
array2 = Object.values({...array1, [1]:"seven"});
console.log(array1);
console.log(array2);
首先找到索引,这里我用图片文档id docId来说明:
const index = images.findIndex((prevPhoto)=>prevPhoto.docId === docId)
this.setState({images: [...this.state.images.slice(0,index), updatedImage, ...this.state.images.slice(index+1)]})
我已经尝试了很多使用展开运算符的方法。我认为当您使用 splice() 时,它会更改主数组。所以我发现的解决方案是将数组克隆到新变量中,然后使用展开运算符拆分它。我用的例子。
var cart = [];
function addItem(item) {
let name = item.name;
let price = item.price;
let count = item.count;
let id = item.id;
cart.push({
id,
name,
price,
count,
});
return;
}
function removeItem(id) {
let itemExist = false;
let index = 0;
for (let j = 0; j < cart.length; j++) {
if (cart[j].id === id) { itemExist = true; break; }
index++;
}
if (itemExist) {
cart.splice(index, 1);
}
return;
}
function changeCount(id, newCount) {
let itemExist = false;
let index = 0;
for (let j = 0; j < cart.length; j++) {
console.log("J: ", j)
if (cart[j].id === id) {
itemExist = true;
index = j;
break;
}
}
console.log(index);
if (itemExist) {
let temp1 = [...cart];
let temp2 = [...cart];
let temp3 = [...cart];
cart = [...temp1.splice(0, index),
{
...temp2[index],
count: newCount
},
...temp3.splice(index + 1, cart.length)
];
}
return;
}
addItem({
id: 1,
name: "item 1",
price: 10,
count: 1
});
addItem({
id: 2,
name: "item 2",
price: 11,
count: 1
});
addItem({
id: 3,
name: "item 3",
price: 12,
count: 2
});
addItem({
id: 4,
name: "item 4",
price: 13,
count: 2
});
changeCount(4, 5);
console.log("AFTER CHANGE!");
console.log(cart);
我正在使用 ... 展开语法替换反应状态数组中的项目。这有效:
let newImages = [...this.state.images]
newImages[4] = updatedImage
this.setState({images:newImages})
是否可以在一行代码中做到这一点?是这样的吗? (这显然行不通...)
this.setState({images: [...this.state.images, [4]:updatedImage})
Object.assign
完成任务:
this.setState({images: Object.assign([], this.state.images, {4: updatedImage}));
...但涉及一个临时对象(最后一个)。尽管如此,只有一个临时对象......如果你用 slice
这样做并展开数组,它会涉及更多的临时对象([=15= 中的两个数组,它们的迭代器,结果对象通过调用迭代器的 next
函数 [在 ...
句柄内] 等创建。
之所以有效,是因为 normal JS arrays aren't really arrays1 (this is subject to optimization, of course), they're objects with some special features. Their "indexes" are actually property names meeting certain criteria2。所以在那里,我们将 this.state.images
分散到一个新数组中,将其作为目标传递到 Object.assign
中,并给 Object.assign
一个对象 属性 命名为 "4"
(是的,它最终是一个字符串,但我们可以将它写成一个数字)我们想要更新的值。
实例:
const a = [0, 1, 2, 3, 4, 5, 6, 7];
const b = Object.assign([], a, {4: "four"});
console.log(b);
如果4
可以是可变的,没关系,你可以使用computed property name(ES2015中的新功能):
let n = 4;
this.setState({images: Object.assign([], this.state.images, {[n]: updatedImage}));
注意 n
周围的 []
。
实例:
const a = [0, 1, 2, 3, 4, 5, 6, 7];
const index = 4;
const b = Object.assign([], a, {[index]: "four"});
console.log(b);
1 披露:那是我贫血的小博客上的 post。
2 是项目符号列表后的第二段:
An integer index is a String-valued property key that is a canonical numeric String (see 7.1.16) and whose numeric value is either +0 or a positive integer ≤ 253-1. An array index is an integer index whose numeric value i is in the range +0 ≤ i < 232-1.
因此 Object.assign
与创建数组然后更新索引 4 的操作相同。
您可以使用地图:
const newImages = this.state.images
.map((image, index) => index === 4 ? updatedImage : image)
this.setState({images: [...this.state.images.slice(0, 4), updatedImage, ...this.state.images.slice(5)]})
修改原作post:更改了切片方法第二个参数中的 3 o a 4 因为第二个参数指向数组中超出最后一个保留的成员,它现在正确回答原题。
这是我的自我解释非一行
const wantedIndex = 4;
const oldArray = state.posts; // example
const updated = {
...oldArray[wantedIndex],
read: !oldArray[wantedIndex].read // attributes to change...
}
const before = oldArray.slice(0, wantedIndex);
const after = oldArray.slice(wantedIndex + 1);
const menu = [
...before,
updated,
...after
]
我参考了@Bardia Rastin 的解决方案,我发现该解决方案在索引值处有错误(它替换了索引 3 而不是 4 处的项目)。
如果要替换有索引值index的item,答案应该是
this.setState({images: [...this.state.images.slice(0, index), updatedImage, ...this.state.images.slice(index + 1)]})
this.state.images.slice(0, index)
是一个新数组,项目从 从 0 到索引 - 1(不包括索引)
this.state.images.slice(index)
是一个新数组,其项目从 index 开始,然后是 .
要正确替换索引 4 处的项目,答案应为:
this.setState({images: [...this.state.images.slice(0, 4), updatedImage, ...this.state.images.slice(5)]})
您可以将数组转换为对象 (...array1
),替换项目 ([1]:"seven"
),然后将其转换回数组 (Object.values
) :
array1 = ["one", "two", "three"];
array2 = Object.values({...array1, [1]:"seven"});
console.log(array1);
console.log(array2);
首先找到索引,这里我用图片文档id docId来说明:
const index = images.findIndex((prevPhoto)=>prevPhoto.docId === docId)
this.setState({images: [...this.state.images.slice(0,index), updatedImage, ...this.state.images.slice(index+1)]})
我已经尝试了很多使用展开运算符的方法。我认为当您使用 splice() 时,它会更改主数组。所以我发现的解决方案是将数组克隆到新变量中,然后使用展开运算符拆分它。我用的例子。
var cart = [];
function addItem(item) {
let name = item.name;
let price = item.price;
let count = item.count;
let id = item.id;
cart.push({
id,
name,
price,
count,
});
return;
}
function removeItem(id) {
let itemExist = false;
let index = 0;
for (let j = 0; j < cart.length; j++) {
if (cart[j].id === id) { itemExist = true; break; }
index++;
}
if (itemExist) {
cart.splice(index, 1);
}
return;
}
function changeCount(id, newCount) {
let itemExist = false;
let index = 0;
for (let j = 0; j < cart.length; j++) {
console.log("J: ", j)
if (cart[j].id === id) {
itemExist = true;
index = j;
break;
}
}
console.log(index);
if (itemExist) {
let temp1 = [...cart];
let temp2 = [...cart];
let temp3 = [...cart];
cart = [...temp1.splice(0, index),
{
...temp2[index],
count: newCount
},
...temp3.splice(index + 1, cart.length)
];
}
return;
}
addItem({
id: 1,
name: "item 1",
price: 10,
count: 1
});
addItem({
id: 2,
name: "item 2",
price: 11,
count: 1
});
addItem({
id: 3,
name: "item 3",
price: 12,
count: 2
});
addItem({
id: 4,
name: "item 4",
price: 13,
count: 2
});
changeCount(4, 5);
console.log("AFTER CHANGE!");
console.log(cart);