javascript 如何根据多个属性值建构新的数组?

gt0wga4j  于 2022-12-10  发布在  Java
关注(0)|答案(3)|浏览(116)

我家里有三个人[“约翰”、“简”、“杰克”],
我们记录谁开/关了门。

logs = [
  { name: "John", status: "opened" },
  { name: "Jane", status: "opened" },
  { name: "Jack", status: "opened" },
  { name: "Jane", status: "closed" },
  { name: "Jack", status: "closed" },
];

你可以看到只有两个人能正确地打开和关闭门。
通过编程,我完成了这3个步骤,从而了解到John是打开门并且从不关闭门的人。

let openers = logs.reduce((acc, log) => {
  if (log.status === "opened") {
    acc.push(log.name);
  }
  return acc;
}, []);

console.log(openers);

let closers = logs.reduce((acc, log) => {
  if (log.status === "closed") {
    acc.push(log.name);
  }
  return acc;
}, []);

console.log(closers);

let result = [];
closers.forEach((closer) => {
  if (openers.includes(closer)) {
    result.push(closer);
  }
});

console.log(result);

我试图在一个reduce()中一次性完成这些操作,但我不太确定。
有人能帮我改进一下吗

logs = [
  { name: "John", status: "opened" },
  { name: "Jane", status: "opened" },
  { name: "Jack", status: "opened" },
  { name: "Jane", status: "closed" },
  { name: "Jack", status: "closed" },
];

let openers = logs.reduce((acc, log) => {
  if (log.status === "opened") {
    acc.push(log.name);
  }
  return acc;
}, []);

console.log(openers);

let closers = logs.reduce((acc, log) => {
  if (log.status === "closed") {
    acc.push(log.name);
  }
  return acc;
}, []);

console.log(closers);

let result = [];
closers.forEach((closer) => {
  if (openers.includes(closer)) {
    result.push(closer);
  }
});

console.log(result);

jogvjijk

jogvjijk1#

您可以使用一个.reduce()来实现这一点,它可以按名称跟踪门的状态:

logs = [
  { name: "John", status: "opened" },
  { name: "Jane", status: "opened" },
  { name: "Jack", status: "opened" },
  { name: "Jane", status: "closed" },
  { name: "Jack", status: "closed" },
];

let statuses = logs.reduce((acc, log) => {
  acc[log.name] = (log.status === 'opened');
  return acc;
}, {});
console.log(statuses);
let culprits = Object.keys(statuses).filter(name => statuses[name]);
console.log(culprits);

输出量:

{
  "John": true,
  "Jane": false,
  "Jack": false
}
[
  "John"
]
6mzjoqzu

6mzjoqzu2#

这肯定会有点复杂,因为人们可以多次打开和关闭门。
这种方法会找出开门次数和关门次数不匹配的人。它将reduces输入到一个中间对象,对于每个名字,如果门是打开的,它会将值加1,如果门是关闭的,它会将值减1。在这之后,只需获取对象的entries,并将计数为0的名字filtering输出。

const logs = [
  { name: "John", status: "opened" },
  { name: "Jane", status: "opened" },
  { name: "Jack", status: "opened" },
  { name: "Jane", status: "closed" },
  { name: "Jack", status: "closed" },
];

const result = Object.entries(logs.reduce((a, v) => {
  a[v.name] = a[v.name] || 0;
  a[v.name] += v.status === 'opened' ? 1 : -1;
  return a;
}, {})).filter(([_, v]) => v).map(([k]) => k);

console.log(result);

如果您考虑到打开和关闭的顺序,则会有额外的复杂性,但该问题没有提供足够的详细信息来解决这些问题。

7vhp5slm

7vhp5slm3#

下面是另一种方式:

const result = logs.reduce((accVal, x) => {
    if (logs.find(y => x.name == y.name && x.status == "opened" && y.status == "closed" )) {
        return Object.assign(accVal, accVal.opened_and_closed.splice(logs.length, 0, x.name));
    }
    else if (logs.find(y => x.name == y.name && x.status == "opened" && y.status != "closed" )) {
        return Object.assign(accVal, accVal.opened_not_closed.splice(logs.length, 0, x.name));
    }
    else {
        return accVal;
    }
},
{ "opened_and_closed": [ ], "opened_not_closed": [ ] } 
);

result值:

{
  opened_and_closed: [ 'Jane', 'Jack' ],
  opened_not_closed: [ 'John' ]
}

相关问题