ऑब्जेक्ट की वस्तुओं के माध्यम से पुनरावर्ती लूप

Aug 17 2020

मैं एक वस्तु के माध्यम से जाने के लिए और एक आईडी के आधार पर आइटम वापस करने के लिए एक पुनरावर्ती फ़ंक्शन लिखने की कोशिश कर रहा हूं। मैं काम करने के लिए इसका पहला भाग प्राप्त कर सकता हूं, लेकिन मैं इस कार्य को पुनरावर्ती तरीके से प्राप्त करने की कोशिश कर रहा हूं और आंखों के नए सेट का उपयोग कर सकता हूं। कोड नीचे है। जब आप स्निपेट चलाते हैं, तो आपको 6 आइटमों की एक सरणी मिलती है, जो कि पहली पुनरावृत्ति के लिए होती है, जो मैं चाहता हूं, लेकिन मैं नेस्टेड आइटम प्राप्त करने के लिए उचित मापदंडों के साथ अपने फ़ंक्शन को कैसे कह सकता हूं? मेरा अंतिम लक्ष्य सभी वस्तुओं को 'Cstm' के साथ शुरू करना है, नेस्टेड लोगों को भी टेबलएंडवैल्यूज सरणी में जोड़ा जाना है। मैं इसके बाद अपने कोड को मॉडल करने की कोशिश कर रहा था: बहु स्तरीय नेस्टेड सरणी जावास्क्रिप्ट से सभी प्रमुख मान प्राप्त करें , लेकिन यह वस्तुओं की एक सरणी के साथ संबंधित है न कि वस्तुओं की वस्तु। कोई भी संकेत या सुझाव जो मुझे मिल सकते हैं वह बहुत सराहना करते हैं।

JSFiddle: https://jsfiddle.net/xov49jLs/

const response = {
  "data": {
    "Cstm_PF_ADG_URT_Disposition": {
      "child_welfare_placement_value": ""
    },
    "Cstm_PF_ADG_URT_Demographics": {
      "school_grade": "family setting",
      "school_grade_code": ""
    },
    "Cstm_Precert_Medical_Current_Meds": [
      {
        "med_name": "med1",
        "dosage": "10mg",
        "frequency": "daily"
      },
      {
        "med_name": "med2",
        "dosage": "20mg",
        "frequency": "daily"
      }
    ],
    "Cstm_PF_ADG_URT_Substance_Use": {
      "dimension1_comment": "dimension 1 - tab1",
      "Textbox1": "text - tab1"
    },
    "Cstm_PF_ADG_Discharge_Note": {
      "prior_auth_no_comm": "auth no - tab2"
    },
    "Cstm_PF_ADG_URT_Clinical_Plan": {
      "cca_cs_dhs_details": "details - tab2"
    },
    "container": {
      "Cstm_PF_Name": {
        "first_name": "same text for textbox - footer",
        "last_name": "second textbox - footer"
      },
      "Cstm_PF_ADG_URT_Demographics": {
        "new_field": "mapped demo - footer"
      },
      "grid2": [
        {
          "Cstm_PF_ADG_COMP_Diagnosis": {
            "diagnosis_label": "knee",
            "diagnosis_group_code": "leg"
          }
        },
        {
          "Cstm_PF_ADG_COMP_Diagnosis": {
            "diagnosis_label": "ankle",
            "diagnosis_group_code": "leg"
          }
        }
      ]
    },
    "submit": true
  }
};

function getNamesAndValues(data, id) {
  const tablesAndValues = [],
        res = data;
 
  Object.entries(res).map(([key, value]) => {
    const newKey = key.split('_')[0].toLowerCase();
    
    // console.log(newKey) // -> 'cstm'
    
    if (newKey === id) {
      tablesAndValues.push({
        table: key,
        values: value
      });
    } else {
      // I can log value and key and see what I want to push 
      // to the tablesAndValues array, but I can't seem to get 
      // how to push the nested items.
      
      // console.log(value);
      // console.log(key);
      
      // getNamesAndValues(value, key)
    }
  });
  
  return tablesAndValues;
}

console.log(getNamesAndValues(response.data, 'cstm'));

जवाब

1 traktor Aug 17 2020 at 07:30

एकल पुश के साथ परिणाम प्राप्त करने के लिए, कोई परिणाम तालिका में फ़ंक्शन को पुनरावर्ती रूप से पास कर सकता है, लेकिन इसे पहली कॉल पर खाली तालिका में डिफ़ॉल्ट रूप से भेज सकता है। मैं भी बदल .mapगया हूँ .forEachक्योंकि वापसी मूल्य का उपयोग नहीं किया जाता है:

const response = {
  "data": {
    "Cstm_PF_ADG_URT_Disposition": {
      "child_welfare_placement_value": ""
    },
    "Cstm_PF_ADG_URT_Demographics": {
      "school_grade": "family setting",
      "school_grade_code": ""
    },
    "Cstm_Precert_Medical_Current_Meds": [
      {
        "med_name": "med1",
        "dosage": "10mg",
        "frequency": "daily"
      },
      {
        "med_name": "med2",
        "dosage": "20mg",
        "frequency": "daily"
      }
    ],
    "Cstm_PF_ADG_URT_Substance_Use": {
      "dimension1_comment": "dimension 1 - tab1",
      "Textbox1": "text - tab1"
    },
    "Cstm_PF_ADG_Discharge_Note": {
      "prior_auth_no_comm": "auth no - tab2"
    },
    "Cstm_PF_ADG_URT_Clinical_Plan": {
      "cca_cs_dhs_details": "details - tab2"
    },
    "container": {
      "Cstm_PF_Name": {
        "first_name": "same text for textbox - footer",
        "last_name": "second textbox - footer"
      },
      "Cstm_PF_ADG_URT_Demographics": {
        "new_field": "mapped demo - footer"
      },
      "grid2": [
        {
          "Cstm_PF_ADG_COMP_Diagnosis": {
            "diagnosis_label": "knee",
            "diagnosis_group_code": "leg"
          }
        },
        {
          "Cstm_PF_ADG_COMP_Diagnosis": {
            "diagnosis_label": "ankle",
            "diagnosis_group_code": "leg"
          }
        }
      ]
    },
    "submit": true
  }
};

function getNamesAndValues(data, id, tablesAndValues = []) {
  const res = data;
 
  Object.entries(res).forEach(([key, value]) => {
    const newKey = key.split('_')[0].toLowerCase();
    if (newKey === id) {
      tablesAndValues.push({
        table: key,
        values: value
      });
    } else {
        getNamesAndValues( value, id, tablesAndValues);    }
  });
    return tablesAndValues;
}

console.log(getNamesAndValues(response.data, 'cstm'));

1 DavidNithaelTorresLima Aug 17 2020 at 07:18

आपको बस बाकी ऑपरेटर के साथ स्टेटमेंट के अंदर tableAndValues ​​पर पुश कॉल करने की आवश्यकता है और मान और आईडी को मापदंडों के रूप में पास करें

const response = {
  "data": {
    "Cstm_PF_ADG_URT_Disposition": {
      "child_welfare_placement_value": ""
    },
    "Cstm_PF_ADG_URT_Demographics": {
      "school_grade": "family setting",
      "school_grade_code": ""
    },
    "Cstm_Precert_Medical_Current_Meds": [
      {
        "med_name": "med1",
        "dosage": "10mg",
        "frequency": "daily"
      },
      {
        "med_name": "med2",
        "dosage": "20mg",
        "frequency": "daily"
      }
    ],
    "Cstm_PF_ADG_URT_Substance_Use": {
      "dimension1_comment": "dimension 1 - tab1",
      "Textbox1": "text - tab1"
    },
    "Cstm_PF_ADG_Discharge_Note": {
      "prior_auth_no_comm": "auth no - tab2"
    },
    "Cstm_PF_ADG_URT_Clinical_Plan": {
      "cca_cs_dhs_details": "details - tab2"
    },
    "container": {
      "Cstm_PF_Name": {
        "first_name": "same text for textbox - footer",
        "last_name": "second textbox - footer"
      },
      "Cstm_PF_ADG_URT_Demographics": {
        "new_field": "mapped demo - footer"
      },
      "grid2": [
        {
          "Cstm_PF_ADG_COMP_Diagnosis": {
            "diagnosis_label": "knee",
            "diagnosis_group_code": "leg"
          }
        },
        {
          "Cstm_PF_ADG_COMP_Diagnosis": {
            "diagnosis_label": "ankle",
            "diagnosis_group_code": "leg"
          }
        }
      ]
    },
    "submit": true
  }
};

function getNamesAndValues(data, id) {
  const tablesAndValues = [],
        res = data;
 
  Object.entries(res).map(([key, value]) => {
    const newKey = key.split('_')[0].toLowerCase();
    
    // console.log(newKey) // -> 'cstm'
    
    if (newKey === id) {
      tablesAndValues.push({
        table: key,
        values: value
      });
    } else {
      // I can log value and key and see what I want to push 
      // to the tablesAndValues array, but I can't seem to get 
      // how to push the nested items.
      
      // console.log(value);
      // console.log(key);
      
      tablesAndValues.push(...getNamesAndValues(value, id))
    }
  });
  
  return tablesAndValues;
}

console.log(getNamesAndValues(response.data, 'cstm'));

या छोटे तरीके से

function getNamesAndValues2(data, id) {
    return Object.entries(data).reduce((arr, [key, value]) => {
        arr.push(
            ...(key.split('_')[0].toLowerCase() === id ? [{ table: key, values: value }] : getNamesAndValues(value, id))
        );
        return arr
    }, []);
}
1 JoeSeifi Aug 17 2020 at 07:49

यहाँ एक कार्यशील संस्करण है। मैं मुख्य फ़ंक्शन को पुनरावर्ती कहता हूं यदि मान या तो एक सरणी या ऑब्जेक्ट है। हर बार टैलींग सरणी की वर्तमान स्थिति में भी गुजर रहा है।

function getNamesAndValues(data, id, tablesAndValues = []) {
  const res = data;
 
  Object.entries(res).map(([key, value]) => {
    const newKey = key.split('_')[0].toLowerCase();
    const item = res[key];

    if (newKey === id) {
      tablesAndValues.push({
        table: key,
        values: value
      });
    }
    
    if(Array.isArray(item)) {
        return item.map(el => getNamesAndValues(el, id, tablesAndValues));
    }

    if(typeof item === 'object') {
        return getNamesAndValues(item, id, tablesAndValues);
    }

  })

  return tablesAndValues;
}

console.log(getNamesAndValues(response.data, 'cstm'));
1 Thankyou Aug 17 2020 at 08:02

यहाँ जनरेटर का उपयोग कर एक और तरीका है -

const keySearch = (t = [], q = "") =>
  filter(t, ([ k, _ ]) => String(k).startsWith(q))

const r = 
  Array.from
    ( keySearch(response, "Cstm")
    , ([ table, values ]) =>
        ({ table, values })
    )

console.log(r)
[
  {
    table: 'Cstm_PF_ADG_URT_Disposition',
    values: { child_welfare_placement_value: '' }
  },
  {
    table: 'Cstm_PF_ADG_URT_Demographics',
    values: { school_grade: 'family setting', school_grade_code: '' }
  },
  {
    table: 'Cstm_Precert_Medical_Current_Meds',
    values: [ [Object], [Object] ]
  },
  {
    table: 'Cstm_PF_ADG_URT_Substance_Use',
    values: {
      dimension1_comment: 'dimension 1 - tab1',
      Textbox1: 'text - tab1'
    }
  },
  {
    table: 'Cstm_PF_ADG_Discharge_Note',
    values: { prior_auth_no_comm: 'auth no - tab2' }
  },
  {
    table: 'Cstm_PF_ADG_URT_Clinical_Plan',
    values: { cca_cs_dhs_details: 'details - tab2' }
  },
  {
    table: 'Cstm_PF_Name',
    values: {
      first_name: 'same text for textbox - footer',
      last_name: 'second textbox - footer'
    }
  },
  {
    table: 'Cstm_PF_ADG_URT_Demographics',
    values: { new_field: 'mapped demo - footer' }
  },
  {
    table: 'Cstm_PF_ADG_COMP_Diagnosis',
    values: { diagnosis_label: 'knee', diagnosis_group_code: 'leg' }
  },
  {
    table: 'Cstm_PF_ADG_COMP_Diagnosis',
    values: { diagnosis_label: 'ankle', diagnosis_group_code: 'leg' }
  }
]

ऊपर, keySearchबस एक विशेषज्ञता है filter-

function* filter (t = [], test = v => v)
{ for (const v of traverse(t)){
    if (test(v))
      yield v
  }
}

जो की एक विशेषज्ञता है traverse-

function* traverse (t = {})
{ if (Object(t) === t)
    for (const [ k, v ] of Object.entries(t))
      ( yield [ k, v ]
      , yield* traverse(v)
      )
}

अपने ब्राउज़र में परिणाम सत्यापित करने के लिए नीचे दिए गए स्निपेट का विस्तार करें -

function* traverse (t = {})
{ if (Object(t) === t)
    for (const [ k, v ] of Object.entries(t))
      ( yield [ k, v ]
      , yield* traverse(v)
      )
}

function* filter (t = [], test = v => v)
{ for (const v of traverse(t)){
    if (test(v))
      yield v
  }
}

const keySearch = (t = [], q = "") =>
  filter(t, ([ k, _ ]) => String(k).startsWith(q))

const response =
  {"data":{"Cstm_PF_ADG_URT_Disposition":{"child_welfare_placement_value":""},"Cstm_PF_ADG_URT_Demographics":{"school_grade":"family setting","school_grade_code":""},"Cstm_Precert_Medical_Current_Meds":[{"med_name":"med1","dosage":"10mg","frequency":"daily"},{"med_name":"med2","dosage":"20mg","frequency":"daily"}],"Cstm_PF_ADG_URT_Substance_Use":{"dimension1_comment":"dimension 1 - tab1","Textbox1":"text - tab1"},"Cstm_PF_ADG_Discharge_Note":{"prior_auth_no_comm":"auth no - tab2"},"Cstm_PF_ADG_URT_Clinical_Plan":{"cca_cs_dhs_details":"details - tab2"},"container":{"Cstm_PF_Name":{"first_name":"same text for textbox - footer","last_name":"second textbox - footer"},"Cstm_PF_ADG_URT_Demographics":{"new_field":"mapped demo - footer"},"grid2":[{"Cstm_PF_ADG_COMP_Diagnosis":{"diagnosis_label":"knee","diagnosis_group_code":"leg"}},{"Cstm_PF_ADG_COMP_Diagnosis":{"diagnosis_label":"ankle","diagnosis_group_code":"leg"}}]},"submit":true}}

const result = 
  Array.from
    ( keySearch(response, "Cstm")
    , ([ table, values ]) =>
        ({ table, values })
    )

console.log(result)

1 ScottSauyet Aug 18 2020 at 00:28

एक यथोचित सुरुचिपूर्ण पुनरावर्ती उत्तर इस तरह दिखाई दे सकता है:

const getNamesAndValues = (obj) => 
  Object (obj) === obj
    ? Object .entries (obj)
        .flatMap (([k, v]) => [
          ... (k .toLowerCase () .startsWith ('cstm') ? [{table: k, value: v}] : []), 
          ... getNamesAndValues (v)
        ])
    : []

const response = {data: {Cstm_PF_ADG_URT_Disposition: {child_welfare_placement_value: ""}, Cstm_PF_ADG_URT_Demographics: {school_grade: "family setting", school_grade_code: ""}, Cstm_Precert_Medical_Current_Meds: [{med_name: "med1", dosage: "10mg", frequency: "daily"}, {med_name: "med2", dosage: "20mg", frequency: "daily"}], Cstm_PF_ADG_URT_Substance_Use: {dimension1_comment: "dimension 1 - tab1", Textbox1: "text - tab1"}, Cstm_PF_ADG_Discharge_Note: {prior_auth_no_comm: "auth no - tab2"}, Cstm_PF_ADG_URT_Clinical_Plan: {cca_cs_dhs_details: "details - tab2"}, container: {Cstm_PF_Name: {first_name: "same text for textbox - footer", last_name: "second textbox - footer"}, Cstm_PF_ADG_URT_Demographics: {new_field: "mapped demo - footer"}, grid2: [{Cstm_PF_ADG_COMP_Diagnosis: {diagnosis_label: "knee", diagnosis_group_code: "leg"}}, {Cstm_PF_ADG_COMP_Diagnosis: {diagnosis_label: "ankle", diagnosis_group_code: "leg"}}]}, submit: true}}

console .log (getNamesAndValues (response))
.as-console-wrapper {max-height: 100% !important; top: 0}

लेकिन यह इतना आसान नहीं है जितना मैं चाहूंगा। यह कोड माचिस की खोज और उसमें प्रयोग किए गए परीक्षण को आउटपुट के प्रारूपण के साथ एक साथ मिलाता है। इसका मतलब है कि यह एक कस्टम फ़ंक्शन है जो समझने के लिए अधिक जटिल है और जितना मैं चाहूंगा उससे कम पुन: प्रयोज्य है।

मैं इस कार्यक्षमता की तीन विशेषता को अलग करते हुए कुछ पुन: प्रयोज्य कार्यों का उपयोग करना पसंद करूंगा। इसलिए, जबकि निम्नलिखित में कोड की अधिक लाइनें शामिल हैं, मुझे लगता है कि यह अधिक समझ में आता है:

const findAllDeep = (pred) => (obj) => 
  Object (obj) === obj
    ? Object .entries (obj)
        .flatMap (([k, v]) => [
          ... (pred (k, v) ? [[k, v]] : []), 
          ... findAllDeep (pred) (v)
        ])
    : []

const makeSimpleObject = (name1, name2) => ([k, v]) => 
 ({[name1]: k, [name2]: v})

const makeSimpleObjects = (name1, name2) => (xs) => 
  xs .map (makeSimpleObject (name1, name2))

const cstmTest = k => 
  k .toLowerCase () .startsWith ('cstm')

const getNamesAndValues = (obj) => 
  makeSimpleObjects ('table', 'values') (findAllDeep (cstmTest) (obj))

const response = {data: {Cstm_PF_ADG_URT_Disposition: {child_welfare_placement_value: ""}, Cstm_PF_ADG_URT_Demographics: {school_grade: "family setting", school_grade_code: ""}, Cstm_Precert_Medical_Current_Meds: [{med_name: "med1", dosage: "10mg", frequency: "daily"}, {med_name: "med2", dosage: "20mg", frequency: "daily"}], Cstm_PF_ADG_URT_Substance_Use: {dimension1_comment: "dimension 1 - tab1", Textbox1: "text - tab1"}, Cstm_PF_ADG_Discharge_Note: {prior_auth_no_comm: "auth no - tab2"}, Cstm_PF_ADG_URT_Clinical_Plan: {cca_cs_dhs_details: "details - tab2"}, container: {Cstm_PF_Name: {first_name: "same text for textbox - footer", last_name: "second textbox - footer"}, Cstm_PF_ADG_URT_Demographics: {new_field: "mapped demo - footer"}, grid2: [{Cstm_PF_ADG_COMP_Diagnosis: {diagnosis_label: "knee", diagnosis_group_code: "leg"}}, {Cstm_PF_ADG_COMP_Diagnosis: {diagnosis_label: "ankle", diagnosis_group_code: "leg"}}]}, submit: true}}

console .log (findAllDeep (cstmTest) (response))
.as-console-wrapper {max-height: 100% !important; top: 0}

पुन: प्रयोज्य की बदलती डिग्री के ये सभी सहायक कार्य हैं:

  • makeSimpleObjectदो प्रमुख नाम लेते हैं, कहते हैं 'foo', और 'bar'एक फ़ंक्शन देता है जो एक दो-तत्व सरणी लेता है, कहती है [10, 20]और उन ऑब्जेक्ट से मेल खाती हुई वस्तु को वापस लौटाती है, जैसे{foo: 10, bar: 20}

  • makeSimpleObjectsदो-तत्व सरणियों के एक सरणी के लिए एक ही बात करता है makeSimpleObjects('foo', 'bar')([[8, 6], [7, 5], [30, 9]]) //=> [{foo: 8, bar: 6}, {foo: 7, bar: 5}, {foo: 30, bar: 9}]:।

  • cstmTestयह जांचने के लिए एक सरल विधेय है कि क्या कुंजी (केस-असंवेदनशील) के साथ शुरू होती है "cstm"

  • और findAllDeepएक विधेय लेता है और एक फ़ंक्शन देता है जो एक ऑब्जेक्ट लेता है और दो-तत्व सरणियों की एक सरणी लौटाता है, जो किसी भी आइटम के लिए कुंजी / मान जोड़े को पकड़ता है जो कि विधेय से मेल खाता है। (विधेय को कुंजी और मूल्य दोनों की आपूर्ति की जाती है; वर्तमान मामले में हमें केवल कुंजी की आवश्यकता होती है, लेकिन यह फ़ंक्शन के लिए या तो समझदार लगता है।

हमारा मुख्य कार्य, मिलान मूल्यों को खोजने और फिर परिणाम को अंतिम प्रारूप में बदलने के लिए getNamesAndValuesउपयोग करता findAllDeep (cstmTest)है makeSimpleObjects ('table', 'values')

ध्यान दें कि findAllDeep, makeSimpleObjectऔर makeSimpleObjectsसभी कार्य कहीं और उपयोगी होने की संभावना है। यहाँ अनुकूलन केवल cstmTestऔर उसके लिए संक्षिप्त परिभाषा में है getNamesAndValues। मैं इसे एक जीत के रूप में गिनूंगा।