【问题标题】:Javascript, filtering array of objects and return all the unique objectsJavascript,过滤对象数组并返回所有唯一对象
【发布时间】:2021-02-26 14:05:36
【问题描述】:

我有一个对象数组,其中包含对象属性:

let allPersons = [
    { id: "abcdefg",
      name: "tom",
      ...
      phone: {
         brand: "blah"
         id: "hijklm"
         ...
     }
   },
   { id: ....}, {...}, {...}
];

我需要做的是过滤这些对象并返回所有电话,按 id 过滤它们,以便返回的所有电话都是唯一的。

我首先尝试检索所有手机:

// allPersons is the full array mentioned above
let phones = [...new Set(allPersons.map(person => person.phone))];

然后我尝试归还所有独特的手机,但没有成功:

let result = phones.map(phone => phone.id).filter((value, index, self) => self.indexOf(value) === index)

这仅返回手机的唯一 ID,但我想要整个对象。我能做什么?

更新: 电话 ID 不是唯一的,例如nokia3310 的 id 为 1,nokia3330 的 id 为 2,依此类推:所以 tom 和 john 可以拥有相同的电话,电话 id 可以重复!

【问题讨论】:

  • 你是指对象的Id,还是Phone Id
  • 手机的 ID 不是唯一的吗?
  • @AndresGardiol 是的,它们是独一无二的,但我想要整个电话对象作为回报
  • @berkobienb the phoneId !
  • @Diego,如果您想返回整个电话对象,请检查我的答案,它会从每个对象中获取整个电话对象并将它们存储在一个您可以使用的数组中

标签: javascript node.js filtering


【解决方案1】:

创建一个由 ID 索引的对象,然后获取对象的值:

const phonesById = Object.fromEntries(
  allPersons.map(
    ({ phone }) => [phone.id, phone]
  )
);
const uniquePhones = Object.values(phonesById);

【讨论】:

  • 天哪,我什至不知道fromEntries 存在,也不知道我可以映射以这种方式编写的整个对象{phone}!非常感谢,我一个人做不到
  • 能否解释一下map 部分?我不认为我已经理解它是如何工作的:)
  • 您可以查看文档以获得更清晰的信息:developer.mozilla.org/es/docs/Web/JavaScript/Referencia/… map 所做的基本上是创建一个新数组,并将调用指定函数的结果应用于其每个元素。 '{ phone }' 部分正在解构“人”对象
  • @Diego .map 将一个数组转换为另一个数组。在这里,它将每个 person 转换为一个条目:一个新对象的键值对,以具有 2 个值的数组的形式。 Object.fromEntries 将有后面的条目键覆盖早期的键,这就是重复数据删除的工作原理。
  • 你的意思是每个phone进入一个条目?
【解决方案2】:

如果您尝试在数组的每个对象中获取电话对象,那么下面的代码将为您完成。

它获取电话对象并将其存储在一个

var objArr = [
    {id: "abcdefg", name: "tom", phone: {brand: "blah", id: "hijklm"}},
    {id: "guidiuqwbd", name: "john", phone: {brand: "hihihih", id: "ayfva"}},
    {id: "yuygeve", name: "doe", phone: {brand: "hahahah", id: "cqcqw"}}
]

var allPhoneObjects = [];
objArr.forEach(function(currObj){
    var phoneObj = currObj.phone;
    allPhoneObjects.push(phoneObj);
});
console.log(allPhoneObjects);

【讨论】:

  • 我认为这个问题并不清楚。当他说“按 id 过滤它们,以便返回的所有电话都是唯一的”时。这让我觉得手机的 ID 可能不是唯一的
  • 如果他能对他的问题进行编辑,使其更具体、更清晰
【解决方案3】:

我建议你以下解决方案

let uniques = new Set();
const phones = allPersons.filter(({phone}) => (
  uniques.has(phone.id) ? false : !!uniques.add(phone.id)
)).map(p => p.phone)

基本上,我们定义一个Set 来记录已处理的电话的ids,并在allPersons 数组上定义一个filter 函数,它只返回尚未在集合中的电话。我们使用 map 来完成仅提取所需的 JSON 部分

编辑 您可以使用 reduce 函数在 allPersons 数组上仅使用一个函数

let uniques = new Set();
const phones = allPersons.reduce( (filtered, {phone}) => {
  if (!uniques.has(phone.id)) {
     filtered.push(phone);
     uniques.add(phone.id);
  }
  return filtered
}, [])

【讨论】:

  • 谢谢,但是通过这个实现,返回了整个 person 对象(这可能很有用!),但是现在我只需要返回每个人的 phone 对象,把它放在一个数组中,并确保没有重复的手机! (查看他们的身份)
  • 嗨@Diego。我现在第二次运行代码,只是为了确保我没有搞砸,但返回的数组是一个电话数组,而不是整个人......如果你运行它,你会得到类似的东西[{brand: "Nokia", id: "abc123"}, {brand: "Sony", id: "def456"}, {brand: "Apple", id: "ghi789"}]
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-01-22
  • 2021-12-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多