0

I have this function that sort some input object based on an array called keys;

const keys = ["token", "agentID", "agentSequence", "allOptions"]

function sortRequest(request) {
  return keys.reduce((sortedRequest, key) => {
    if (key in request) {
      sortedRequest[key] = request[key]
    }
    return sortedRequest
  }, {})
}


console.log(sortRequest({
  allOptions: false,
  agentSequence: 6,
  agentID: 123,
  token: 'test',
  notVisible: true
}));

The only problem is if some value of the input is not present on the array it will be lost on the returned object. I'm trying to fix this issue, but couldn't get it. The idea is to get each property of the object.

7
  • fyi object property is practically guaranteed but could change. you shouldn't absolutely rely on it. Commented Nov 13, 2020 at 20:01
  • What you're doing there is filtering the object by the keys available. It's because you're only looping through the keys you've specified. Are you trying to get an object who's keys are sorted in alphabetical order? If so you could set the const keys to Object.keys(request).sort() and then run your reduce. But in general a sorted object isn't really worthwhile and you shouldn't be relying on any sorting of keys in an object. Commented Nov 13, 2020 at 20:01
  • I don't understand exactly what you trying to do. When you say sort input object what do u mean. Commented Nov 13, 2020 at 20:02
  • No, no alphabetically sorting, just to follow the order from the keys arrays. In that array token is first, and so on. I need to send this object sorted with the way that array is sorted. I know that objects sorting is a very large issue, with many scopes where may it fails, but this object will be sent to an external SOAP api made in 1999 with a lot of history behind... I can't control what receives that API (it has many if inside a for, etc...). Commented Nov 13, 2020 at 20:05
  • Why don't you do the ordering in the function that sends to the SOAP API, rather than in the object itself? Commented Nov 13, 2020 at 20:10

3 Answers 3

1

Simple forEach and spread will do the trick.

const input = {
  allOptions: false,
  agentSequence: 6,
  agentID: 123,
  token: 'test',
  notVisible: true
};

const keys = ["token", "agentID", "agentSequence", "allOptions"];

function orderInput(input, keys) {
  let ordered = {};
  keys.forEach(function (key) {
    if (key in input) {
      ordered[key] = input[key];
    }
  });

  return {...ordered, ...input};
}

console.log(orderInput(input, keys));

Sign up to request clarification or add additional context in comments.

Comments

1

After getting the properties that are in keys, do a second pass over the original object and add in the properties that are missing.

const keys = ["token", "agentID", "agentSequence", "allOptions"]

function sortRequest(request) {
  const result = keys.reduce((sortedRequest, key) => {
    if (key in request) {
      sortedRequest[key] = request[key]
    }
    return sortedRequest
  }, {});
  return Object.entries(request).reduce((sortedRequest, [key, value]) => {
    if (!(key in keys)) {
      sortedRequest[key] = value;
    }
    return sortedRequest;
  }, result)
}


console.log(sortRequest({
  allOptions: false,
  agentSequence: 6,
  agentID: 123,
  token: 'test',
  notVisible: true
}));

Comments

1

Objects cannot be reordered. Objects are by definition unordered. Some javascript engine (most of them these days) do have some sort order but do not depend on it since the standard does not specify object key sorting behavior.

If you need a specific key order you need a Map. Or if you want to do it the traditional way you need an array:

[
  ["token", "agentID", "agentSequence", "allOptions"]
  { key: "token", value: 'test' },
  { key: "agentID", value: 123 },
  { key: "agentSequence", value: 6 },
  { key: "allOptions", value: false },
  { key: "notVisible", value: true}
]

This of course does not answer your question. Instead do not even attempt to do what you are doing.

2 Comments

ES6 says that non-numeric keys preserve insertion order. See stackoverflow.com/questions/5525795/…
That's a misreading of the spec. ES6 simply says that the keys maintain the order returned by Object.keys() and then don't specify what that order is. Originally I also thought that's what the spec said until one of my answers was disputed and I had to read the wording of the spec more carefully

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.