Search code examples
javascriptarrayssortingobject

Clone an array of objects into a new array of Object but with re-ordered keys


I have an array of objects where I need to change the order of the keys. e.g.

let data = [
  {
    "Summer": "green",
    "Winter": "white",
    "Spring": "yellow",
    "Autumn": "orange",
    "Total": 0,
    "Number": 0,
    "Difference": 0
  },
  {
    "Summer": "green",
    "Winter": "white",
    "Spring": "yellow",
    "Autumn": "orange",
    "Total": 0,
    "Number": 0,
    "Difference": 0
  },
]

what I want to achieve is:

let updated = [
  {
    "Total": 0,
    "Number": 0,
    "Summer": "green",
    "Spring": "yellow",
    "Autumn": "orange",
    "Winter": "white",
    "Difference": 0
  },
  {
    "Total": 0,
    "Number": 0,
    "Summer": "green",
    "Spring": "yellow",
    "Autumn": "orange",
    "Winter": "white",
    "Difference": 0
  }
]

I have tried cloning into a new array with the order I want and also object.assign which doesn't give me the expected result.

let newArr = [];
for (let i in data) {
  newArr.push(
    data[i].Total,
    data[i].Number,
    data[i].Summer,
    data[i].Spring,
    data[i].Autumn,
    data[i].Winter,
    data[i].Difference
  )
}

does not work as exptected and also

const objectOrder = {
  'Total': null,
  'Number': null,
  'Summer': null,
  'Spring': null,
  'Autumn': null,
  'Winter': null,
  'Difference': null,
}
for (let i of data) {
  const addObjectResource = Object.assign(objectOrder, data[i]);
  newArr.push(addObjectResource)
}

Solution

  • Let's start by using:

    • Object.entries()
    • Array.sort()
    • Object.fromEntries()

    let data = [{
        "Summer": "green",
        "Winter": "white",
        "Spring": "yellow",
        "Autumn": "orange",
        "Total": 0,
        "Number": 0,
        "Difference": 0
      },
      {
        "Summer": "green",
        "Winter": "white",
        "Spring": "yellow",
        "Autumn": "orange",
        "Total": 0,
        "Number": 0,
        "Difference": 0
      },
    ]
    
    const order = ["Total", "Number", "Summer", "Spring", "Autumn", "Winter", "Difference"];
    let answer1 = data.map( e => Object.fromEntries(
        Object.entries(e)
        .sort((a, b) => order.indexOf(a[0]) - order.indexOf(b[0]))
    ) );
    console.log(answer1);

    The destructuring answer posted by @pilchard looks interesting and is much more efficient than the answer I posted:

    let data = [{
        "Summer": "green",
        "Winter": "white",
        "Spring": "yellow",
        "Autumn": "orange",
        "Total": 0,
        "Number": 0,
        "Difference": 0
      },
      {
        "Summer": "green",
        "Winter": "white",
        "Spring": "yellow",
        "Autumn": "orange",
        "Total": 0,
        "Number": 0,
        "Difference": 0
      },
    ]
    
    let answer2 = data.map( ({ Total, Number, Summer, Spring, Autumn, Winter, Difference, })
                         => ({ Total, Number, Summer, Spring, Autumn, Winter, Difference, })); 
    console.log(answer2);