我正试图弄清楚如何通过嵌套对象数组中属性的值是否包含值stopped
来对对象数组进行排序。当该值存在于任何嵌套的对象数组中时,我需要将父对象排序到顶部,从那里开始,我尝试按id
对排序列表进行二次排序。
const arr = [{
id: 1,
things: [{
thing_id: 1,
status: 'started',
},
{
thing_id: 1,
status: 'started',
},
],
},
{
id: 2,
things: [{
thing_id: 1,
status: 'started',
},
{
thing_id: 1,
status: 'started',
},
{
thing_id: 1,
status: 'stopped',
},
],
},
{
id: 3,
things: [{
thing_id: 1,
status: 'started',
},
{
thing_id: 1,
status: 'started',
},
{
thing_id: 1,
status: 'started',
},
{
thing_id: 1,
status: 'started',
},
],
}
]
// desired result
[{
id: 2,
things: [{
thing_id: 1,
status: 'started',
},
{
thing_id: 1,
status: 'started',
},
{
thing_id: 1,
status: 'stopped',
},
],
},
{
id: 1,
things: [{
thing_id: 1,
status: 'started',
},
{
thing_id: 1,
status: 'started',
},
],
},
{
id: 3,
things: [{
thing_id: 1,
status: 'started',
},
{
thing_id: 1,
status: 'started',
},
{
thing_id: 1,
status: 'started',
},
{
thing_id: 1,
status: 'started',
},
],
}
]
const checkStopped = (things) => things.some((el) => el.status === 'stopped');
const desired = arr.sort((a, b) => checkStopped(b.things) - checkStopped(a.things));
arr.sort((a, b) => {
if (a.things.some(thing => thing.status === "stopped")) {
return -1;
} else {
return a.id - b.id;
}
});
你只需要排序,检查当前被检查的对象是否至少有一个";事物;具有状态"0";"停止";,否则为正常的数字顺序。
arr.sort((a, b) => {
const stoppeds_in_a = a.things.map(obj => obj.status).filter(status => status === 'stopped').length
const stoppeds_in_b = b.things.map(obj => obj.status).filter(status => status === 'stopped').length
// I want that who has more 'stoppeds' occurrences first
return stoppeds_in_b - stoppeds_in_a
})
您可以引入一个助手函数,根据提供的回调对集合进行分区。然后将它们连接在一起以创建所需的结果。
const arr = [{id:1,things:[{thing_id:1,status:'started'},{thing_id:1,status:'started'}]},{id:2,things:[{thing_id:1,status:'started'},{thing_id:1,status:'started'},{thing_id:1,status:'stopped'}]},{id:3,things:[{thing_id:1,status:'started'},{thing_id:1,status:'started'},{thing_id:1,status:'started'},{thing_id:1,status:'started'}]}];
const [withStopped, withoutStopped] = partition(arr,
item => item.things.some(item => item.status == "stopped")
);
const result = withStopped.concat(withoutStopped);
console.log(result);
// helper
function partition(iterable, fn) {
const partitions = { "true": [], "false": [] };
for (const item of iterable) partitions[!!fn(item)].push(item);
return [partitions[true], partitions[false]];
}
这实际上是递归的一项好任务。但是,如果结构是固定的,我采取了两个循环和一个条件。如果这是真的,我将数组推入全局res变量。
const arr = [
{
id: 1,
things: [
{
thing_id: 1,
status: 'started',
},
{
thing_id: 1,
status: 'started',
},
],
},
{
id: 2,
things: [
{
thing_id: 1,
status: 'started',
},
{
thing_id: 1,
status: 'started',
},
{
thing_id: 1,
status: 'stopped',
},
],
},
{
id: 3,
things: [
{
thing_id: 1,
status: 'started',
},
{
thing_id: 1,
status: 'started',
},
{
thing_id: 1,
status: 'started',
},
{
thing_id: 1,
status: 'started',
},
],
}
]
const res = [];
arr.forEach(function(e) {
let val = Object.values(e.things)
val.forEach((t) => {
if(t.status == "stopped") {
res.push(e)
}
})
})
console.log('res', res)
您应该执行类似的操作
const Firstresult = [];//with stopped
const SecontPartresult = [];//without stopped
arr.forEach(element => {
element.things.forEach(thing => {
if (thing.status == "stopped") {
if (Firstresult.filter(x => x.id == element.id).length == 0) {
Firstresult.push(element)
}
} else if (element.things.filter(x => x.status == "stopped").length === 0) {
if (SecontPartresult.filter(x => x.id == element.id && x.things !== "stopped").length == 0) {
SecontPartresult.push(element)
}
}
});
});
SecontPartresult.forEach(element => {
Firstresult.push(element)
});
console.table(Firstresult)