简体   繁体   中英

looking to sort items in object to match order of array

I'm trying to reorder the items in an object so they will match the order of an array. The object is the row data and the array is the column names.

Here are the order of column names I want to match:

columnNames    [
    "System.Id",
    "System.WorkItemType",
    "System.Title",
    "System.AssignedTo",
    "System.State",
    "Microsoft.VSTS.Common.ActivatedDate",
    "System.ChangedDate",
    "Microsoft.VSTS.Common.ClosedDate"
    ]

Here is an example of the object items I'm trying to reorder:

 fields = {"System.Id":7993,"System.WorkItemType":"Task","System.State":"Closed","System.AssignedTo":"Jack Smith","System.ChangedDate":"2022-07-19T12:14:25.193Z","System.Title":"Update Dev Environment","Microsoft.VSTS.Common.ActivatedDate":"2022-07-19T12:13:49.713Z","Microsoft.VSTS.Common.ClosedDate":"2022-07-19T12:14:25.193Z"}

Ultimately I just want the values of each item in the object placed in an array which matches the order of the columnNames array, so like this:

rowArray = [
7993,"Task","Update Dev Environment","Jack Smith","Closed","2022-07-19T12:14:25.193Z","2022-07-19T12:13:49.713Z","2022-07-19T12:14:25.193Z"]

I get the fields object from calling an API. In order to get only the fields I want I loop through part of the API response.

Here's my entire code if it helps to see what I'm trying to do:

queryItems = result from API call

queryItems.forEach((item) => {
        let sortingfields = [];
        let sortedfields = [];
        let rowArray = [];

        //loop through fields part of each response item and add it to new array sortingfields
        Object.entries(item.fields).forEach(([key, value]) => {
            switch(key){
                case 'System.AssignedTo':
                    sortingfields.push(key, item.fields[key].displayName);
                    break;
                case 'System.ChangedDate':
                    const changedDate = item.fields[key].toLocaleString(DateTime.DATETIME_FULL);
                    sortingfields.push(key, changedDate);
                    break;
                case 'Microsoft.VSTS.Common.ActivatedDate':
                    const activatedDate = item.fields[key].toLocaleString(DateTime.DATETIME_FULL);
                    sortingfields.push(key, activatedDate);
                    break;
                case 'Microsoft.VSTS.Common.ClosedDate':
                    const closedDate = item.fields[key].toLocaleString(DateTime.DATETIME_FULL);
                    sortingfields.push(key, closedDate);
                    break;
                default:
                    sortingfields.push(key, item.fields[key]);
                    break;
            }
        })
        // sort array items so they match the order of the columnNames array
        sortedfields = sortingfields.sort((entryA, entryB) => {
            const [keyA] = entryA;
            const [keyB] = entryB;
            return columnNames.indexOf(keyA) - columnNames.indexOf(keyB)
        })
        // loop through sorted array and retrieve only the values
        for (let s of sortedfields){
            rowArray.push(sortedfields[s]);
        }
        // add array as a new row to Excel file using ExcelJS
        let row = sheet.addRow(rowArray);

    })

Now the error I get is Failure Exception: entryA is not iterable . I don't understand why given sortingfields is an array.

you can use map for that

you just map over the keys you want and get it from the object like this

 const orderData = (data, order) => order.map(k => data[k]) const columnNames = [ "System.Id", "System.WorkItemType", "System.Title", "System.AssignedTo", "System.State", "Microsoft.VSTS.Common.ActivatedDate", "System.ChangedDate", "Microsoft.VSTS.Common.ClosedDate" ] const single = {"System.Id":7993,"System.WorkItemType":"Task","System.State":"Closed","System.AssignedTo":"Jack Smith","System.ChangedDate":"2022-07-19T12:14:25.193Z","System.Title":"Update Dev Environment","Microsoft.VSTS.Common.ActivatedDate":"2022-07-19T12:13:49.713Z","Microsoft.VSTS.Common.ClosedDate":"2022-07-19T12:14:25.193Z"} const data = [{"System.Id":7993,"System.WorkItemType":"Task","System.State":"Closed","System.AssignedTo":"Jack Smith","System.ChangedDate":"2022-07-19T12:14:25.193Z","System.Title":"Update Dev Environment","Microsoft.VSTS.Common.ActivatedDate":"2022-07-19T12:13:49.713Z","Microsoft.VSTS.Common.ClosedDate":"2022-07-19T12:14:25.193Z"}, {"System.Id":7993,"System.WorkItemType":"Task","System.State":"Closed","System.AssignedTo":"Jack Smith","System.ChangedDate":"2022-07-19T12:14:25.193Z","System.Title":"Update Dev Environment","Microsoft.VSTS.Common.ActivatedDate":"2022-07-19T12:13:49.713Z","Microsoft.VSTS.Common.ClosedDate":"2022-07-19T12:14:25.193Z"}] console.log(orderData(single, columnNames)) console.log(data.map(d => orderData(d, columnNames)))

I'm not really sure of what you want to achieve but here is my answer:

const fieldEntries = Object.entries(fields);
const entriesResult = fieldEntries.sort((entryA, entryB) => {
  const [keyA] = entryA;
  const [keyB] = entryB;
  return columnNames.indexOf(keyA) - columnNames.indexOf(keyB)
})
const objResult = Object.fromEntries(entriesResult)

This gives the following value for objResult :

{
System.Id:7993
System.WorkItemType:"Task"
System.Title:"Update Dev Environment"
System.AssignedTo:"Jack Smith"
System.State:"Closed"
Microsoft.VSTS.Common.ActivatedDate:"2022-07-19T12:13:49.713Z"
System.ChangedDate:"2022-07-19T12:14:25.193Z"
Microsoft.VSTS.Common.ClosedDate:"2022-07-19T12:14:25.193Z"
}

Sandbox: https://playcode.io/932608

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