简体   繁体   中英

Typescript: parse nested interface data with forEach()

CountTargetsData is an interface I use as a type to later parse JSON data. As seen below, the data has many nesting.

interface CountTargetsData {
  data: {
    [state: string]: {
      [date: string]: {
        [index: string]: { [id: string]: { [targets: string]: number } },
      },
    },
  };
}

const parseCounters = useCallback(
  async (responseDeploymentData: CountTargetsData) => {
    //WANT TO PARSE ID AND TARGETS HERE
  }
);

Given all the nests, how can I use the forEach() method to access the id and targets for each CountTargetsData ?

Sample Data:

    "stateA": {
        "2016-06-03": [
            {
                "1200": {
                    "count_targets": 1,
                    "count_targets_excluded": 0,
                    "count_targets_pending": 0,
                    "count_targets_in_progress": 0,
                    "count_targets_completed": 0,
                    "count_targets_failed": 1
                }
            }
        ],
        "2016-06-07": [
            {
                "1455": {
                    "count_targets": 1,
                    "count_targets_excluded": 0,
                    "count_targets_pending": 0,
                    "count_targets_in_progress": 0,
                    "count_targets_completed": 1,
                    "count_targets_failed": 0
                }
            }
        ]
         
    }
}

Update

Your type doesn't match the example data you provided

It should be:

interface CountTargetsData {
  data: {
    [state: string]: {
      [date: string]: ({
        [index: string]: {
          [id: string]: {
            [targets: string]: number
          }
        },
      })[],
    },
  };
}

 const data = { "stateA": { "2016-06-03": [{ "1200": { "count_targets": 1, "count_targets_excluded": 0, "count_targets_pending": 0, "count_targets_in_progress": 0, "count_targets_completed": 0, "count_targets_failed": 1 } }], "2016-06-07": [{ "1455": { "count_targets": 1, "count_targets_excluded": 0, "count_targets_pending": 0, "count_targets_in_progress": 0, "count_targets_completed": 1, "count_targets_failed": 0 } }] } } Object.entries(data).forEach(([state, value]) => { Object.entries(value).forEach(([date, value]) => { value.forEach(obj => { Object.entries(obj).forEach(([id, value]) => { Object.entries(value).forEach(([target, value]) => { console.log(state, date, id, target, value) }) }) }) }) })

Old answer

You can't use .forEach directly as the nested data is stored as objects and not arrays.

Try using Object.entries / Object.values first or use for..of loop:

const parseCounters = useCallback(
    async (
      responseDeploymentData: CountTargetsData
    ) => {
      Object.values(responseDeploymentData.data).forEach(state => {
        Object.values(state).forEach(date => {
          // and so on
        })
      })
  }
const parseCounters = useCallback(
    async (
      responseDeploymentData: CountTargetsData
    ) => {
      for (const state of responseDeploymentData.data) {
        for (const date of state) {
          // and so on
        }
      }
  }

Think about using recursion or DFS algorithm

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM