-1

There are way too many questions asked on converting a Javascript Object to an Array.

But I can't find any example of converting Javascript Object to an Array with guaranteed order.

I would like to explain you by an example:

If I have an object called person like:

var person = {
    f_name: "John",
    l_name: "Doe",
    age: 20
}

I want an Array that will always look like:

["John", "Doe", 20]

I mean the values in the Array should always be in the same order as my object.

Reply to @KevinB:

enter image description here

Vishal
  • 4,990
  • 8
  • 57
  • 140
  • 4
    javascript objects don't have an order – marvel308 Sep 08 '17 at 18:48
  • @marvel308 I know that. But I mean the order in which I specified Javascript Object's keys. – Vishal Sep 08 '17 at 18:49
  • Sounds simple enough. you wouldn't even need to loop. – Kevin B Sep 08 '17 at 18:49
  • 1
    But you did not specify the order of the Objects keys, you just specify that the keys exist. As soon as you declare an object literal all promise of the key order is lost. – bhspencer Sep 08 '17 at 18:50
  • @KevinB Sounds simple enough but its too complicated when order is important – Vishal Sep 08 '17 at 18:50
  • 1
    @Vishal but you have already declared what the order should be. so create your array using said keys in said order. `[o.foo, o.bar, o.baz]` – Kevin B Sep 08 '17 at 18:50
  • If you can't do that, then you haven't adequately described your problem. – Kevin B Sep 08 '17 at 18:58
  • @KevinB Here I have just given an example. But my actual question is: I am getting values from `DBF` file using `node-dbf` library which returns me each row as object instead of an array. And the keys contain some unicode characters. So, I want the array in which order is same as order of `DBF` columns. Wait I will upload a screenshot of my object. – Vishal Sep 08 '17 at 19:01
  • then yeah, you've asked an unclear question. Fixing it now will invalidate answers. – Kevin B Sep 08 '17 at 19:01
  • @KevinB Ok, I am sorry for that. But can you please take a look at image in question? – Vishal Sep 08 '17 at 19:04
  • Possible duplicate of [Does JavaScript Guarantee Object Property Order?](https://stackoverflow.com/questions/5525795/does-javascript-guarantee-object-property-order) – bhspencer Sep 08 '17 at 19:07
  • we don't know how the data is being generated, whether it's being modified in any way before we get access to it, whether or not it has a defined column list with an order, or anything really about this data. therefore we can't assume that it's order would be preserved by a for..in loop or object.values – Kevin B Sep 08 '17 at 19:11
  • Javascript is full of surprise. Maybe try to use `const` to see what's going on... – TGrif Sep 08 '17 at 19:25
  • @Vishal If you are getting same object with same keys then i would say get the keys of that object by `Object.keys(yourobj)` then sort those keys and according to that sorted keys, make your array. It will guarantee the order of the values everytime.It should look something like `Object.keys(yourObj).sort().map((k) => yourObj[k])` – Prakash Sharma Sep 08 '17 at 19:29

4 Answers4

1

If you want to guarantee order you will need to define that order in a data structure that guarantees it, like a list.

For example, you could do something like this:

let person = {
    f_name: "John",
    l_name: "Doe",
    age: 20
}
let orderedKeys = ["f_name", "l_name", "age"];
let personArray = orderedKeys.map(function (key) {
    return person[key];
});
Stanley Liu
  • 140
  • 2
  • 8
  • this is basically what @BenM has showed but he got downvotes. keys are placed in the order that they exist in the object. simple as that – turmuka Sep 08 '17 at 18:58
  • Basically, but not the same. He is trusting the implementation of Object.values, but I am writing my own implementation, because I am unsure how various versions of JS implement that method. As you can see in the comments from that answer there are varying ways older and newer JS versions implement it. I wouldn't doubt it is fine for most cases; however I would rather trust my own implementation in this case which runs on all JS versions 100% of the time. If he mentioned a warning that various versions which may implement the method different, there might have been less downvotes. – Stanley Liu Sep 08 '17 at 19:26
0

Assuming that the properties are always enumerable, you can use Object.values():

var person = {
    f_name: "John",
    l_name: "Doe",
    age: 20
}

var vals = Object.values(person);
console.log(vals);
BenM
  • 49,881
  • 23
  • 107
  • 158
  • Javascript objects make no guarantee of the order of their properties. Your solution might work with one implementation of JavaScript but not in another. – bhspencer Sep 08 '17 at 18:52
  • @bhspencer that's not entirely true – Kevin B Sep 08 '17 at 18:53
  • i really don't know, i have upvoted because the *elites* are downvoting because I think this question is too easy – turmuka Sep 08 '17 at 18:53
  • that is not true @bhspencer – turmuka Sep 08 '17 at 18:53
  • @KevinB do you have a link to the JavaScript spec that shows that the keys have order? – bhspencer Sep 08 '17 at 18:53
  • 1
    spec, no, but it is documented that object keys do have an expected order under some circumstances. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/values – Kevin B Sep 08 '17 at 18:54
  • the keys have an order in the way they are placed. so they are ordered when you use `Object.values()` and `for in` loop @bhspencer – turmuka Sep 08 '17 at 18:54
  • 1
    @bhspencer Check this out: https://jsfiddle.net/gaeb0bgc/ Notice that JS has preserved the *definition* order of my object literals. – BenM Sep 08 '17 at 18:54
  • 1
    Can anyone provide an example of how `Object.values()` would **not** produce the desired output (i.e. taking a defined object and outputting its values in the same order)? – BenM Sep 08 '17 at 18:56
  • I can't to be honest @BenM – turmuka Sep 08 '17 at 18:56
  • @bhspencer: It's complicated: https://ecma-international.org/ecma-262/8.0/#sec-ordinaryownpropertykeys . That doesn't mean that every operation that gets keys or iterates over properties gets them in that order. But there is *some* order. – Felix Kling Sep 08 '17 at 18:56
  • 1
    @BenM: `{foo: 'bar', 42: 21}`. – Felix Kling Sep 08 '17 at 18:57
  • @KevinB your links states "The ordering of the properties is the same as that given by looping over the property values of the object manually" Which is not the same as saying that they have the same order that they were created with. Only that for...in and Object.values() will have the same order. You do not get to define what that order is. It may be that in some implementations your solution works but it is not guaranteed to work in all implementations. – bhspencer Sep 08 '17 at 18:58
  • 1
    Thanks @FelixKling. Is that the only instance (i.e. integer-based property name)? – BenM Sep 08 '17 at 19:00
  • @bhspencer oh, sorry, wrong link. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...in first sentence. – Kevin B Sep 08 '17 at 19:00
  • so that means they have the same order using those two, right? and that was the answer to the question @bhspencer – turmuka Sep 08 '17 at 19:00
  • the numbers come first in the placements, that's the only thing to consider. not too complicated. not a reason to downvote this answer @FelixKling but thanks for pointing that out – turmuka Sep 08 '17 at 19:01
  • 3
    @BenM: The order that most browsers seem to implement (and which is what is defined in `OrdinaryOwnPropertyKeys` (see the link I posted earlier)) is: integer keys ascending, string keys in insertion order, symbols in insertion order. – Felix Kling Sep 08 '17 at 19:02
  • @KevinB see this from the same page you linked to "A for...in loop iterates over the properties of an object in an arbitrary order (see the delete operator for more on why one cannot depend on the seeming orderliness of iteration, at least in a cross-browser setting)." – bhspencer Sep 08 '17 at 19:02
  • right, and in this case we aren't dealing with deleted modified or added properties. – Kevin B Sep 08 '17 at 19:04
  • So, unless we're dealing with integer keys (which is highly unlikely given the OP), we can assume most browsers have implemented insertion order, which means we do know the order of a well-defined object such as the OP posted. @bhspencer – BenM Sep 08 '17 at 19:04
  • @BenM but not if 'delete' has ever been used. – bhspencer Sep 08 '17 at 19:05
  • https://stackoverflow.com/questions/5525795/does-javascript-guarantee-object-property-order – bhspencer Sep 08 '17 at 19:06
  • 2
    The more important parts of the spec are these: [`EnumerableOwnProperties`](https://tc39.github.io/ecma262/#sec-enumerableownproperties), which is called when calling `Object.values` and [`EnumerateObjectProperties`](https://tc39.github.io/ecma262/#sec-enumerate-object-properties), where it says: *"**The mechanics and order of enumerating the properties is not specified** but must conform to the rules specified below."* Even though it *appears* that the order is defined, it isn't. Which makes sense because that would be a backwards incompatible change. – Felix Kling Sep 08 '17 at 19:07
  • @bhspencer well from that case what I see is we can create array of pairs which might be the best option – turmuka Sep 08 '17 at 19:08
  • 2
    @bhspencer *However in ES2015 and later non-integer keys will be returned in insertion order.* – BenM Sep 08 '17 at 19:08
0

javascript objects don't have an order, you would have to define it in the following way

var person = {
    f_name: "John",
    l_name: "Doe",
    age: 20
}

var defined_order = ['f_name', 'l_name', 'age'];

let result = [];
for(let prop of defined_order){
    result.push(person[prop]);
}

console.log(result);
marvel308
  • 9,593
  • 1
  • 16
  • 31
0

Here I have just given an example. But my actual question is: I am getting values from DBF file using node-dbf library which returns me each row as object instead of an array. And the keys contain some unicode characters. So, I want the array in which order is same as order of DBF columns.

So it's not actually about your percieved order of keys in the object, but the order of columns in the file. That changes everything.

peeked into the lib you're using, this should do:

var columns;
parser.on('header', function(header) {
    columns = header.fields.map(field => field.name);
    console.log("columns", columns);
});

parser.on('record', function(record) {
    var row = columns.map(key => record[key]);
    console.log("row", row);
});

or

parser.on('record', function(record) {
    var row = this.header.fields.map(field => record[field.name]);
    console.log("row", row);
});
Thomas
  • 8,708
  • 1
  • 10
  • 21