Red
Red

Reputation: 7324

How to shift values through the keys of an array-like object?

For an array I can do:

array.push(array.shift())

var array = [0, 1, 2, 3, 4, 5];
array.push(array.shift())

console.log(array); // [1, 2, 3, 4, 5, 0]

How can I do the same for an object?

Input

var object = {0: 'Fiat', 1: 'Audi', 2: 'BMW', 3: 'Citroën'}

How can I move {0: 'Fiat'} to the end of the object

Expected output:

{0: 'Audi', 1: 'BMW', 2: 'Citroën', 3: 'Fiat'}

Upvotes: 1

Views: 2890

Answers (7)

Nina Scholz
Nina Scholz

Reputation: 386756

You could convert you object with the given keys as index to an array, apply the shifting and convert back to an object.

var object = { 0: 'Fiat', 1: 'Audi', 4: 'BMW', 5: 'Citroën' },
    array = Object.keys(object).reduce((r, k, i) => (r[i] = object[k], r), []);

array.push(array.shift());

console.log(Object.assign({}, array)); // { 0: "Audi", 1: "BMW", 2: "Citroën", 3: "Fiat" }

A different approach, while respecting the keys.

var object = { 0: 'Fiat', 1: 'Audi', 4: 'BMW', 5: 'Citroën' },
    keys = Object.keys(object);
    result = Object.assign(...keys.map((k, i) => ({ [k]: object[keys[(i + 1) % keys.length]] })));

console.log(result); // { 0: "Audi", 1: "BMW", 4: "Citroën", 5: "Fiat" }

Upvotes: 3

Christophe Roussy
Christophe Roussy

Reputation: 17049

Teaching: Objects are usually based on a Hash table for lookup by key. As a consequence this usually means you do not have order.

myObj[key] => find value by computing hash of key => returns value

Upvotes: 0

giwiro
giwiro

Reputation: 336

As Suren said, the object does not guarantee the insertion order. I suggest another approach for example:

const o = {0: 'Fiat', 1: 'Audi', 2: 'BMW', 3: 'Citroën'};
const k = Object.keys(o);
k.push(k.shift());
const result = k.map((v, i) => ({[i]: o[v]}))
   .reduce((acum, v) => Object.assign(acum, v), {});

The approach here is to create and index array, apply the logic (push and shift) then re-build the object with map, and then merge them into one object with reduce. I think this could be shorter (just the reduce) but i wanted to split this up to be more clear.

Upvotes: 0

juzraai
juzraai

Reputation: 5953

You can convert your object into an array, do the reordering on the array and convert the array back to an object:

function toObject(arr) {
  var rv = {};
  for (var i = 0; i < arr.length; ++i)
    rv[i] = arr[i];
  return rv;
}

function toArray(object) {
  return Object.keys(object).map(function (key) { return object[key]; });
}


var object = {0: 'Fiat', 1: 'Audi', 2: 'BMW', 3: 'Citroën'}
var array = toArray(object);
array.push(array.shift());
object = toObject(array);

console.log(object);

Upvotes: 1

marvel308
marvel308

Reputation: 10458

You can use the following way

var object = {0: 'Fiat', 1: 'Audi', 2: 'BMW', 3: 'Citroën'};

var result = Object.keys(object).map(e => object[e]);
//console.log(result);

result.push(result.shift());
//console.log(result);

let ans = Object.assign({}, result);
console.log(ans);

Upvotes: 4

Lazar Ljubenović
Lazar Ljubenović

Reputation: 19764

You should not rely on ordering of object's keys in JavaScript. It's not defined by standard. Objects by definition do not have an ordering, so there is no "end" of the object. It simply doesn't make sense to "move" a key of an object anywhere, since there's no ordering.

The data-structure which does have orders are arrays.

Your object is almost array-like, because all of its keys are consecutive numbers, but it's missing a lenght property. With length, you could turn it into an actual array with Array.from(object).

Upvotes: 0

Suren Srapyan
Suren Srapyan

Reputation: 68675

The object's properties does not have any guarantee on the order, in which they may appear, concise there is no concept as order. I think you need to think more and can find another solution, which does not depend on the properties order.

Upvotes: 1

Related Questions