【问题标题】:Remove an array item nested inside of an object删除嵌套在对象内的数组项
【发布时间】:2019-01-08 06:35:26
【问题描述】:

我正在尝试根据数组中的标题属性从对象数组中删除特定项目。我一直遇到一个问题,我可以查看数组项,但我无法根据删除函数中输入的参数将项从数组中拼接出来。我刚刚从函数中的else 语句中收到错误消息。

我已尝试使用find, forEach, findIndex 并匹配该大小写,以测试根据索引或key 'text' 的文本值删除结果。在论坛推荐中搜索答案之前,我将我尝试过的所有功能都注释掉了。我的所有配方函数以及我的 createIngredient 函数都在工作,它向配方数组添加一个对象。但是我一直在努力工作的removeIngredient 函数并不是因为上面提到的问题。

let recipes = []

// Read existing recipes from localStorage
const loadRecipes = () => {
    const recipesJSON = localStorage.getItem('recipes')

    try {
        return recipesJSON ? JSON.parse(recipesJSON) : []
    } catch (e) {
        return []
    } 
}

// Expose recipes from module
const getRecipes = () => recipes

const createRecipe = () => {
    const id = uuidv4()
    const timestamp = moment().valueOf()

    recipes.push({
        id: id,
        title: '',
        body: '',
        createdAt: timestamp,
        updatedAt: timestamp,
        ingredient: []
    })
    saveRecipes()

    return id
}

// Save the recipes to localStorage
const saveRecipes = () => {
    localStorage.setItem('recipes', JSON.stringify(recipes))
}

// Remove a recipe from the list
const removeRecipe = (id) => {
    const recipeIndex = recipes.findIndex((recipe) => recipe.id === id)

    if (recipeIndex > -1) {
        recipes.splice(recipeIndex, 1)
        saveRecipes()
    }
}

// Remove all recipes from the recipe array
const cleanSlate = () => {
    recipes = []
    saveRecipes()
}

const updateRecipe = (id, updates) => {
    const recipe = recipes.find((recipe) => recipe.id === id)

    if (!recipe) {
        return
    }

    if (typeof updates.title === 'string') {
        recipe.title = updates.title
        recipe.updatedAt = moment().valueOf()
    }

    if (typeof updates.body === 'string') {
        recipe.body = updates.body
        recipe.updateAt = moment().valueOf()
    }

    saveRecipes()
    return recipe
}

const createIngredient = (id, text) => {
    const recipe = recipes.find((recipe) => recipe.id === id)

    const newItem = {
        text,
        have: false
    }
    recipe.ingredient.push(newItem)
    saveRecipes()
}

const removeIngredient = (id) => {
    const ingredient = recipes.find((recipe) => recipe.id === id)
    console.log(ingredient)
    const allIngredients = ingredient.todo.forEach((ingredient) => console.log(ingredient.text))

    // const recipeIndex = recipes.find((recipe) => recipe.id === id)

    // for (let text of recipeIndex) {
    //     console.log(recipdeIndex[text])
    // }

// Attempt 3
    // if (indexOfIngredient === 0) {
    //     ingredientIndex.splice(index, 1)
    //     saveRecipes()
    // } else {
    //     console.log('error')
    // }
    // Attempt 2
    // const recipe = recipes.find((recipe) => recipe.id === id)
    // const ingredients = recipe.todo 
    // // let newItem = ingredients.forEach((item) => item)

    // if (ingredients.text === 'breadcrumbs') {
    //     ingredients.splice(ingredients, 1)
    //     saveRecipes()
    // }
    // Attempt 1
    // const ingredientName = ingredients.forEach((ingredient, index, array) => console.log(ingredient, index, array))
    // console.log(ingredientName)

    // const recipeIndex = recipes.findIndex((recipe) => recipe.id === id)

    // if (recipeIndex > -1) {
    //     recipes.splice(recipeIndex, 1)
    //     saveRecipes()
    // }
}

recipes = loadRecipes()

输出

{id: "ef88e013-9510-4b0e-927f-b9a8fc623450", title: "Spaghetti", body: "", createdAt: 1546878594784, updatedAt: 1546878608896, …}
recipes.js:94 breadcrumbs
recipes.js:94 noodles
recipes.js:94 marinara
recipes.js:94 meat
recipes.js:94 ground beef
recipes.js:94 milk

所以我可以查看上面打印的输出并查看ingredients 数组中的每个项目,但是尝试根据index 数字或key 拼接项目对我来说不起作用到目前为止,我已经尝试过的函数以及我在 Stackoverflow 上找到的关于对象、数组和拼接方法的信息。

【问题讨论】:

  • 您应该考虑编辑问题,以便清楚地显示您开始使用的数据以及您希望在最后看到的数据。如果所有事件处理程序都不是问题的一部分,那么它们可能不需要出现在问题中。

标签: javascript arrays javascript-objects array-splice


【解决方案1】:

如果我理解正确(在阅读了您的代码中注释掉的尝试之后),您正试图从与传递给 removeIngredient() 函数的 id 对应的配方中删除“面包屑”成分。

在这种情况下,也许您可​​以通过Array#filter 方法采取稍微不同的方法从配方todo 数组中删除成分?

您可以按以下方式使用filter(),通过以下过滤逻辑从todo 数组中“过滤掉”(即删除)“面包屑”成分:

// Keep any ingredients that do not match ingredient (ie if ingredient
// equals "breadcrumbs")
todo.filter(todoIngredient => todoIngredient !== ingredient) 

你可以考虑修改你的removeIngredient()函数;

  • 向函数参数添加额外的ingredient 参数。这允许您指定要从与recipeId 对应的配方中删除的成分

  • 并且,介绍filter() 的想法,如下所述:


const removeIngredient = (recipeId, ingredient) => {

    const recipe = recipes.find(recipe => recipe.id === recipeId)

    if(recipe) {

        // Filter recipe.todo by ingredients that do not match  
        // ingredient argument, and reassign the filtered array 
        // back to the recipie object we're working with
        recipe.todo = recipe.todo.filter(todoIngredient => 
                                         (todoIngredient !== ingredient));
    }

}

现在,当您为每种成分引入“删除”按钮时,您将调用removeIngredient(),如下所示:

var recipeId = /* got id from somewhere */
var ingredientText = /* got ingredient from somewhere */

removeIngredient( recipeId, ingredientText );

希望这会有所帮助!

【讨论】:

  • 丹尼,谢谢!我觉得我可能错误地表达了我期望的结果。我尝试了过滤器方法,看起来它正在做它应该做的事情并返回一个只有面包屑的新数组。最终,我想要的是拥有每个对象,例如面包屑、面条、marinara 每个旁边都有一个“删除”按钮,如果用户单击它,该函数将从数组中拼接项目。这就是我最终试图通过removeIngredient 函数实现的目标。我可能应该提到这一点。
  • @Ang 不客气-您希望我更新答案以允许通过removeIngredient() 删除不同的成分吗?
  • 是的,丹尼!谢谢。
  • 没问题@Ang!刚刚更新了答案 - 这有帮助吗?
  • 是的,先生!我感谢您的帮助!我将此标记为已解决。
猜你喜欢
  • 2021-08-23
  • 1970-01-01
  • 1970-01-01
  • 2020-12-20
  • 2021-12-28
  • 2017-04-25
  • 1970-01-01
  • 2020-08-02
  • 2021-07-03
相关资源
最近更新 更多