javascript 是否在一行代码中使用扩展语法替换数组项?[重复]

ca1c2owp  于 2023-01-16  发布在  Java
关注(0)|答案(8)|浏览(117)
    • 此问题在此处已有答案**:

(9个答案)
上个月关门了。
我使用... spread语法替换react state数组中的一个元素。

let newImages = [...this.state.images]
newImages[4] = updatedImage
this.setState({images:newImages})

有没有可能在一行代码中完成这件事?类似于这样?(这显然行不通......)

this.setState({images: [...this.state.images, [4]:updatedImage})
4ioopgfo

4ioopgfo1#

使用Array.slice

this.setState({
  images: [
    ...this.state.images.slice(0, 4),
    updatedImage,
    ...this.state.images.slice(5),
  ],
});

从原始帖子编辑:更改了slice方法的第二个参数中的3 o a 4,因为第二个参数指向的数组成员超出了保留的最后一个成员,所以它现在正确地回答了原始问题。

svmlkihl

svmlkihl2#

一旦change array by copy提案得到广泛支持(它处于第3阶段,因此应该会进入JavaScript引擎),您就可以使用新的with方法来实现这一点:

// Using a Stage 3 proposal, not widely supported yet as of Nov 17 2022
this.setState({images: this.state.images.with(4, updatedImage)});

在此之前,Object.assign将执行以下任务:

this.setState({images: Object.assign([], this.state.images, {4: updatedImage}));

...但是涉及到一个临时对象(末尾的那个)。不过,只有一个临时对象...如果你用slice并展开数组来做这个,它涉及到更多的临时对象(slice的两个数组,它们的迭代器,通过调用迭代器的next函数[在...句柄内]创建的结果对象,等等)。
它之所以有效,是因为normal JS arrays aren't really arrays 1*(当然,这需要进行优化)*,它们是具有一些特殊特性的对象。它们的“索引”实际上是满足某些条件的属性名2。因此,我们将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可以是变量,那就可以了,你可以使用一个计算属性名(ES 2015中的新特性):

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披露:这是我贫血博客上的帖子。
2这是项目符号列表后的第二段:

  • integer index* 是一个字符串值的属性键,它是一个规范的数字字符串(见7.1.16),其数值是**+0**或一个≤ 253-1的正整数。array index 是一个整数索引,其数值 i 在+0 ≤ i〈232-1的范围内。

所以Object.assign的作用和创建数组然后更新索引4的作用是一样的。

yfwxisqw

yfwxisqw3#

您可以使用Map:

const newImages = this.state.images
  .map((image, index) => index === 4 ? updatedImage : image)
hujrc8aj

hujrc8aj4#

可以将数组转换为对象(...array1),替换项目([1]:"seven"),然后将其转换回数组(Object.values):

array1 = ["one", "two", "three"];
array2 = Object.values({...array1, [1]:"seven"});
console.log(array1);
console.log(array2);
dluptydi

dluptydi5#

这是我的自我解释非一行

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
 ]
bmp9r5qi

bmp9r5qi6#

我参考了@Bardia Rastin解决方案,我发现该解决方案在索引值处有一个错误(它替换了索引为3而不是4的项)。
如果要替换具有索引值index的项,则答案应为

this.setState({images: [...this.state.images.slice(0, index), updatedImage, ...this.state.images.slice(index + 1)]})

this.state.images.slice(0, index)是一个新数组,其项从0开始到index - 1(不包括index)
this.state.images.slice(index)是一个新数组,它包含从**index开始的项以及之后的项。
要正确替换索引4处的项目,答案应为:

this.setState({images: [...this.state.images.slice(0, 4), updatedImage, ...this.state.images.slice(5)]})
f4t66c6m

f4t66c6m7#

首先找到索引,这里我使用图像文档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)]})
8mmmxcuj

8mmmxcuj8#

我已经尝试了很多使用spread操作符的方法。我认为当你使用splice()的时候它会改变主数组。所以我发现的解决方案是用新的变量克隆数组,然后用spread操作符拆分它。我用的例子。

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);

相关问题