AshClarke
AshClarke

Reputation: 3078

Arrange array of objects by corresponding array of strings

I have an array of strings in a specific order and would like to arrange a different array of objects to match the original array order.

var arrangement = ["third", "first" "second"];

var myObjs = [
  {
    name: "thing",
    position: "first"
  },
  {
    name: "thing",
    position: "second"
  },
  {
    name: "thing",
    position: "third"
  }
];

So that the output would be:

var myObjs = [
  {
    name: "thing",
    position: "third"
  },
  {
    name: "thing",
    position: "first"
  },
  {
    name: "thing",
    position: "second"
  }
];

Any ideas on a good way to approach this?

Cheers,

Upvotes: 0

Views: 58

Answers (3)

6502
6502

Reputation: 114569

First you need to "index" the object array:

var objpos = {};
objects.forEach(function(obj, ix) { objpos['!' + obj.name] = ix; });

Then you can build the result

var result = arrangement.map(function(name) {
    return objects[objpos['!' + n]];
});

The ! is my habit of always adding it in front of keys when using objects as dictionaries (to avoid problems with the key "constructor").

Upvotes: 1

eladcon
eladcon

Reputation: 5825

Use indexOf function of the first array on the current elements you are sorting:

myObjs.sort(function(a, b) { 
    return arrangement.indexOf(a.position) - arrangement.indexOf(b.position);
})

Upvotes: 4

T.J. Crowder
T.J. Crowder

Reputation: 1075159

I would build a map (an object) keyed by the position values from the first array, with the index of each entry as the value; e.g.:

var map = arrangement.reduce(function(obj, value, index) {
    obj[value] = index;
    return obj;
}, {});

Then I'd use Array#sort on myObjs with a comparator function that looks up the position values of the two entries it's given on the map:

myObjs.sort(function(a, b) {
    return map[a.position] - map[b.position];
});

Live example:

var arrangement = ["third", "first", "second"];

var myObjs = [
        {
            name: "thing",
            position: "first"
        },
        {
            name: "thing",
            position: "second"
        },
        {
            name: "thing",
            position: "third"
        }
    ];

var map = arrangement.reduce(function(obj, value, index) {
    obj[value] = index;
    return obj;
}, {});

myObjs.sort(function(a, b) {
    return map[a.position] - map[b.position];
});

snippet.log("Result: " + JSON.stringify(myObjs));
<!-- Script provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 -->
<script src="http://tjcrowder.github.io/simple-snippets-console/snippet.js"></script>

Upvotes: 2

Related Questions