代码之家  ›  专栏  ›  技术社区  ›  Kokodoko

在一行代码中用扩展语法替换数组条目?

  •  41
  • Kokodoko  · 技术社区  · 8 年前

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

    有没有可能在一行代码中实现这一点?像这样的?(这显然不起作用……)

    this.setState({images: [...this.state.images, [4]:updatedImage})
    
    8 回复  |  直到 7 年前
        1
  •  50
  •   Julio Spinelli    4 年前

    使用 Array.slice

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

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

        2
  •  25
  •   T.J. Crowder    6 年前

    Object.assign

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

    ...但涉及到一个临时对象(最后一个)。不过,只有一个临时对象。。。如果你这样做 slice 在展开数组时,它涉及几个临时对象(来自 ,它们的迭代器,通过调用迭代器的 next ... 手柄等)。

    它之所以有效是因为 normal JS arrays aren't really arrays (当然,这需要优化) ,它们是具有一些特殊特征的对象。它们的“索引”实际上是属性名 meeting certain criteria 2. . 好了,我们开始分散了 this.state.images 作为目标,给予 具有名为的属性的对象 "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.

    2. 这是项目符号列表后的第二段:

    是一个字符串值属性键,它是一个规范的数字字符串(请参见7.1.16),其数值为 +0 -1.An 是一个整数索引,其数值为 一、 在+0范围内 一、 32 -1.

    对象分配 执行与创建-the-array-then-update-index-4相同的操作。

        3
  •  12
  •   CD..    8 年前

    您可以使用地图:

    const newImages = this.state.images
      .map((image, index) => index === 4 ? updatedImage : image)
    
        4
  •  7
  •   furnaceX    6 年前

    可以将阵列转换为对象(即 ...array1 [1]:"seven" Object.values ) :

    array1 = ["one", "two", "three"];
    array2 = Object.values({...array1, [1]:"seven"});
    console.log(array1);
    console.log(array2);
        5
  •  3
  •   webmaster    7 年前

     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
     ]
    
        6
  •  2
  •   Leniel Maccaferri    6 年前

    如果要替换具有索引值index的项,答案应该是

    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) 是一个新数组,其项目从 索引及其后

    this.setState({images: [...this.state.images.slice(0, 4), updatedImage, ...this.state.images.slice(5)]})
    
        7
  •  1
  •   Julio Spinelli    4 年前

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

    我尝试了很多使用扩展运算符的方法。我认为当使用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);