[英]Sort array of objects by property value within nested array of objects
我試圖弄清楚如何通過嵌套對象數組中的屬性值是否包含值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',
},
],
}
]
arr.sort((a, b) => {
if (a.things.some(thing => thing.status === "stopped")) {
return -1;
} else {
return a.id - b.id;
}
});
您只需進行排序,檢查當前正在檢查的對象是否至少有一個狀態為“已停止”的“事物”,否則為正常的數字順序。
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 checkStopped = (things) => things.some((el) => el.status === 'stopped'); const desired = arr.sort((a, b) => checkStopped(b.things) - checkStopped(a.things));
您可以引入一個輔助函數,該函數根據提供的回調對集合進行分區。 然后將它們連接在一起以創建所需的結果。
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)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.