【问题标题】:Remove object property from the nested object in the array从数组中的嵌套对象中删除对象属性
【发布时间】:2021-10-29 12:08:43
【问题描述】:

我有以下书籍。我想写一个函数来接收目标书和语言,从嵌套对象中删除该书(键,值)并返回新数组。

let books = [
  {
    language: 'spanish',
    books: {
      book_1: 'book1_spanish',
      book_2: 'book2_spanish',
      book_3: 'book3_spanish'
    }
  },
  {
    language: 'italian',
    books: {
      book_1: 'book1_italian',
      book_2: 'book2_italian',
      book_3: 'book3_italian'
    }
  }
];

let targetBook = { book_1: 'book1_spanish' };
let language = 'spanish';

我被困在循环嵌套对象上。

function removeTargetBook(lan, target) {
  return books.map(book => {
    if (book.language == lan) {
      Object.values(book).map(value => {});
    }
  });
}

它应该返回没有 book_1 的相同数组:'book1_spanish'。 这是我的堆栈闪电战:https://stackblitz.com/edit/js-yxcrbq

谢谢。

【问题讨论】:

标签: javascript arrays object nested-object


【解决方案1】:

您想使用delete 运算符。

我冒昧地扩展了您的代码,以向您展示如何在 forEach 循环中使用对象的 key 比进行键/值对比较更有效。另请注意,我将原始 books 对象保持不变,这对于单元可测试代码和数据完整性很重要,但您可以根据需要更改/实现。

let books = [
  {
    language: 'spanish',
    books: {
      book_1: 'book1_spanish',
      book_2: 'book2_spanish',
      book_3: 'book3_spanish'
    }
  },
  {
    language: 'italian',
    books: {
      book_1: 'book1_italian',
      book_2: 'book2_italian',
      book_3: 'book3_italian'
    }
  }
];

let targetBook = { book_1: 'book1_spanish' };
let language = 'spanish';
let target = Object.keys(targetBook)[0]; // we only need the 'key' of the targetBook
let result;

function removeTargetBook(books, lan, target) {
  books.forEach(elem => { // some instead of forEach works here as well
    elem.language === lan && (delete elem.books[target]);
  });
  
  return books;
}
// multiple tests for correctness
result = removeTargetBook(books, language, 'fool proof test');
console.log(result);
result = removeTargetBook(books, language, target);
console.log(result);
result = removeTargetBook(books, language, 'book_2');
console.log(result);
result = removeTargetBook(books, language, 'book_3');
console.log(result);

【讨论】:

  • 谢谢,帮了大忙。
  • @zana10 有时您不需要函数,在上述解决方案中,除非您在多个地方“删除书籍”,否则我不会将函数用于单个回调
  • 所使用的数据结构不允许单个项目搜索,因为所有内容都存储在对象数组中,我会将数据结构重新排列为一个大对象,键是语言和值作为书籍的内容,正如@RicardoSaracino 提到的那样,您将能够绕过回调函数的需要以及按语言匹配的循环
【解决方案2】:

我的版本太复杂了:

let books = [{
    language: 'spanish',
    books: {
      book_1: 'book1_spanish',
      book_2: 'book2_spanish',
      book_3: 'book3_spanish'
    }
  },
  {
    language: 'italian',
    books: {
      book_1: 'book1_italian',
      book_2: 'book2_italian',
      book_3: 'book3_italian'
    }
  }
];

let targetBook = {
  book_1: 'book1_spanish'
};
let language = 'spanish';

function removeTargetBook(lan, target) {
  return books.map(book => {
    if (book.language === lan) {

      return {
        language: book.language,
        books: Object.assign(...Object.keys(book.books).map((key) => ({
          [key]: book.books[key]
        })).filter((e) => (Object.keys(e)[0] !== Object.keys(target)[0]) && Object.values(e)[0] !== Object.values(target)[0])),
      }
    } else {
      return book
    }
  })
}
console.log(removeTargetBook(language, targetBook))

【讨论】:

    【解决方案3】:

    我认为这样的事情应该可以工作

    function removeTargetBook(lan, target) {
      books.some(book => {
        if (book.language == lan) {
          delete book.books[Object.keys(target)[0]];
          return true;
        }
      });
      return books
    }
    

    【讨论】:

    • 请添加更多详细信息以扩展您的答案,例如工作代码或文档引用。
    猜你喜欢
    • 2021-01-30
    • 1970-01-01
    • 2020-10-30
    • 2021-12-28
    • 2020-12-07
    • 1970-01-01
    • 2020-08-02
    • 1970-01-01
    • 2019-11-02
    相关资源
    最近更新 更多