ค้นหาเว็บไซต์

javascript - วิธีการกรองอาร์เรย์ซ้อนโดยการค้นหา


ฉันมีอาร์เรย์ของวัตถุที่ฉันต้องการกรองโดยการเปรียบเทียบคุณสมบัติที่ซ้อนกันกับคำค้นหา

ตัวอย่างเช่น:

let array = [
  {
    category: 15,
    label: "Components",
    value: "a614741f-7d4b-4b33-91b7-89a0ef96a099",
    children: [
      {
        category: 1,
        label: "Carousel1",
        diId: 55946,
        // as you can see there are many children nested array of object
        children: [{ label: "nodatafoundmessage", value: "47d18fb2-3e63-4542-ad0e-e5e09acb5016", children: [] }],
        value: "be5e027b-9163-4cfb-8816-0c8e3b816086"
      },
      {
        category: 2,
        label: "Checkbox1",
        diId: 193909,
        children: [{ label: "datafound", value: "47d18sb2-3e63-4542-ad0e-e5e09acb5016", children: [] }],
        value: "045e8786-2165-4e1e-a839-99b1b0ceef57"
      }
    ]
  },
  {
    value: "4be22726-850c-4905-ab3b-039fcf607d55",
    label: "Default",
    children: [
      {
        category: 5,
        defaultValueType: 1,
        label: "Empty",
        toType: "String",
        value: "ebedb43f-4c53-491f-8954-d030321845cd"
      },
      {
        category: 5,
        defaultValueType: 2,
        label: "Space",
        toType: "String",
        value: "2d0e1429-572b-4f21-9f83-3340bafff95a"
      },
      {
        category: 5,
        defaultValueType: 8,
        label: "Current Username",
        toType: "String",
        value: "25f6b40a-33c7-4f17-b29d-99e8d1e4e33c"
      },
      {
        category: 5,
        defaultValueType: 9,
        label: "Current Location",
        toType: "Location",
        value: "ed59da2f-318d-4599-9085-4d9d769a27d7"
      }
    ]
  },
  {
    category: 4,
    label: "Fixed Value",
    isFixed: true,
    value: "28e90e3e-a20b-4499-9593-061a7d1e7bd6"
    // as you can see there is no children in this object
  }
]};

สิ่งที่ฉันพยายามจะทำให้สำเร็จคือถ้าฉันค้นหาคำว่า 'nodata' ตัวอย่างเช่น ผลลัพธ์ของฉันควรเป็น

let array = [
  {
    category: 15,
    label: "Components",
    value: "a614741f-7d4b-4b33-91b7-89a0ef96a099",
    children: [
      {
        category: 1,
        label: "Carousel1",
        diId: 55946,
        // as you can see there are many children nested array of object
        children: [{ label: "nodatafoundmessage", value: "47d18fb2-3e63-4542-ad0e-e5e09acb5016", children: [] }],
        value: "be5e027b-9163-4cfb-8816-0c8e3b816086"
      }
    ]
  }
];

อีกตัวเลือกหนึ่ง ถ้าฉันค้นหา 'สปา' ผลลัพธ์ของฉันควรเป็น

let array = [
  {
    value: "4be22726-850c-4905-ab3b-039fcf607d55",
    label: "Default",
    children: [
      {
        category: 5,
        defaultValueType: 2,
        label: "Space",
        toType: "String",
        value: "2d0e1429-572b-4f21-9f83-3340bafff95a"
      }
    ]
  }
];

ฉันสับสนมากและตัดสินใจที่จะขอความช่วยเหลือ ขอบคุณสำหรับความช่วยเหลือของพวกคุณนะทุกคน!

คำตอบ #1

ฟังก์ชันต่อไปนี้ควรช่วยคุณได้:

function searchData(dataArray, searchTerm) {
  return dataArray.flatMap(obj => {
    const objHasSearchTerm = Object.entries(obj)
      .some(([key, value]) => key !== 'children' && String(value).toLowerCase().includes(searchTerm.toLowerCase()));
    
    if (objHasSearchTerm && !obj.children) return [obj];
    
    const matchedChildren = searchData(obj.children ?? [], searchTerm);
    return objHasSearchTerm || matchedChildren.length > 0
      ? [{
        ...obj,
        children: matchedChildren,
      }]
      : [];
  })
}

มันจะวนซ้ำผ่านอาร์เรย์ของข้อมูล มองหาข้อมูลใด ๆ ที่มีคำค้นหาที่ระบุ และหากพบ จะนำไปวางในอ็อบเจ็กต์ที่สร้างขึ้นใหม่ มันจะรักษารูปร่างซ้อนกันของอ็อบเจ็กต์ไว้ ซึ่งอาจเป็นสิ่งที่ต้องการหรือไม่ก็ได้ อย่าลังเลที่จะแก้ไขอัลกอริทึมให้เหมาะกับความต้องการของคุณเอง

let allData = [
  {
    category: 15,
    label: "Components",
    value: "a614741f-7d4b-4b33-91b7-89a0ef96a099",
    children: [
      {
        category: 1,
        label: "Carousel1",
        diId: 55946,
        // as you can see there are many children nested array of object
        children: [{ label: "nodatafoundmessage", value: "47d18fb2-3e63-4542-ad0e-e5e09acb5016", children: [] }],
        value: "be5e027b-9163-4cfb-8816-0c8e3b816086"
      },
      {
        category: 2,
        label: "Checkbox1",
        diId: 193909,
        children: [{ label: "datafound", value: "47d18sb2-3e63-4542-ad0e-e5e09acb5016", children: [] }],
        value: "045e8786-2165-4e1e-a839-99b1b0ceef57"
      }
    ]
  },
  {
    value: "4be22726-850c-4905-ab3b-039fcf607d55",
    label: "Default",
    children: [
      {
        category: 5,
        defaultValueType: 1,
        label: "Empty",
        toType: "String",
        value: "ebedb43f-4c53-491f-8954-d030321845cd"
      },
      {
        category: 5,
        defaultValueType: 2,
        label: "Space",
        toType: "String",
        value: "2d0e1429-572b-4f21-9f83-3340bafff95a"
      },
      {
        category: 5,
        defaultValueType: 8,
        label: "Current Username",
        toType: "String",
        value: "25f6b40a-33c7-4f17-b29d-99e8d1e4e33c"
      },
      {
        category: 5,
        defaultValueType: 9,
        label: "Current Location",
        toType: "Location",
        value: "ed59da2f-318d-4599-9085-4d9d769a27d7"
      }
    ]
  },
  {
    category: 4,
    label: "Fixed Value",
    isFixed: true,
    value: "28e90e3e-a20b-4499-9593-061a7d1e7bd6"
    // as you can see there is no children in this object
  }
];



function searchData(dataArray, searchTerm) {
  return dataArray.flatMap(obj => {
    const objHasSearchTerm = Object.entries(obj)
      .some(([key, value]) => key !== 'children' && String(value).toLowerCase().includes(searchTerm.toLowerCase()));
    
    if (objHasSearchTerm && !obj.children) return [obj];
    
    const matchedChildren = searchData(obj.children ?? [], searchTerm);
    return objHasSearchTerm || matchedChildren.length > 0
      ? [{
        ...obj,
        children: matchedChildren,
      }]
      : [];
  })
}

console.log('----- Search: nodata')
console.log(JSON.stringify(searchData(allData, 'nodata'), null, 2))
console.log('----- Search: spa')
console.log(JSON.stringify(searchData(allData, 'spa'), null, 2))