Wonka
Wonka

Reputation: 8674

lodash - Move object to first place in array?

I have an array of objects, with type of fruit/vegetable:

For the one type vegetable I have, I want it to be the first item in the array, but I am not sure how to do so with lodash.

var items = [
    {'type': 'fruit', 'name': 'apple'},
    {'type': 'fruit', 'name': 'banana'},
    {'type': 'vegetable', 'name': 'brocolli'}, // how to make this first item
    {'type': 'fruit', 'name': 'cantaloupe'}
];

Here is a fiddle with my attempt: https://jsfiddle.net/zg6js8af/

How can I get type vegetable to be the first item in the array regardless of its current index?

Upvotes: 19

Views: 19964

Answers (4)

Kevin Le - Khnle
Kevin Le - Khnle

Reputation: 10857

Here's a concise solution in ES6 that uses the Array's reduce function:

const items = [
  { type: 'fruit', name: 'apple' },
  { type: 'fruit', name: 'banana' },
  { type: 'vegetable', name: 'brocolli' },
  { type: 'fruit', name: 'cantaloupe' }
]

const final = items.reduce(
  (accumulator, current) =>
    current.type === 'vegetable'
      ? [current, ...accumulator]
      : [...accumulator, current],
  []
)
console.log(final)

Upvotes: 0

SeregPie
SeregPie

Reputation: 1253

Using lodash _.sortBy. If the type is vegetable, it will be sorted first, otherwise second.

let items = [
  {type: 'fruit', name: 'apple'},
  {type: 'fruit', name: 'banana'},
  {type: 'vegetable', name: 'brocolli'},
  {type: 'fruit', name: 'cantaloupe'},
];

let sortedItems = _.sortBy(items, ({type}) => type === 'vegetable' ? 0 : 1);

console.log(sortedItems);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js"></script>


Here is another solution without using lodash.

function sortBy(array, fn) {
  return array.map(v => [fn(v), v]).sort(([a], [b]) => a - b).map(v => v[1]);
}

let items = [
  {type: 'fruit', name: 'apple'},
  {type: 'fruit', name: 'banana'},
  {type: 'vegetable', name: 'brocolli'},
  {type: 'fruit', name: 'cantaloupe'},
];

let sortedItems = sortBy(items, ({type}) => type === 'vegetable' ? 0 : 1);

console.log(sortedItems);

Upvotes: 31

stasovlas
stasovlas

Reputation: 7416

you can do it with ordering by type in desc direction:

var res = _.orderBy(items, ['type'], ['desc']);

or using partition

var res = _.chain(items)
    .partition({type: 'vegetable'})
    .flatten()
    .value();

Upvotes: 2

Bruno Grieder
Bruno Grieder

Reputation: 29824

Why use lodash when you do not need it (and can write functional code using a single reduce) ?

var items = [
  {'type': 'fruit', 'name': 'apple'},
  {'type': 'fruit', 'name': 'banana'},
  {'type': 'vegetable', 'name': 'brocolli'},
  {'type': 'fruit', 'name': 'cantaloupe'}
];

var final = items.reduce(function(arr,v) {
  if (v.type === 'vegetable') return [v].concat(arr)
  arr.push(v)
  return arr
},[]);
alert(JSON.stringify(final));

Upvotes: 3

Related Questions