У меня есть массив объектов
let myArray = [
{
id: 'first',
name: 'john',
},
{
id: 'second',
name: 'Emmy',
},
{
id: 'third',
name: 'Lazarus',
}
]
и массив
let sorter = ['second', 'third', 'first']
Я хотел бы использовать lodash
сортировки lodash
для сортировки объектов в соответствии с их положением в sorter
. Чтобы выход был
let mySortedArray = [
{
id: 'second',
name: 'Emmy',
},
{
id: 'third',
name: 'Lazarus',
},
{
id: 'first',
name: 'john',
}
]
Можно ли это сделать?
Вы можете добиться этого, используя карту и найти:
let myArray = [
{
id: "first",
name: "john"
},
{
id: "second",
name: "Emmy"
},
{
id: "third",
name: "Lazarus"
}
];
let sorter = ["second", "third", "first"];
let mySortedArray = sorter.map(x => myArray.find(y => y.id === x));
console.log(mySortedArray);
Используя lodash, вы можете использовать _.sortBy
let myArray = [
{
id: 'first',
name: 'john',
},
{
id: 'second',
name: 'Emmy',
},
{
id: 'third',
name: 'Lazarus',
}
]
let sorter = ['second', 'third', 'first']
console.log(_.sortBy(myArray,(i) => {return sorter.indexOf(i.id)}))
.as-console-wrapper { max-height: 100% !important; top: 0; }
<script src="/lodash.min.js"></script>
Поскольку у вас есть index
массив в случае sorter
вы можете _.keyBy
использовать основной массив, а затем использовать sorter
для доступа по индексу:
let myArray = [ { id: 'first', name: 'john', }, { id: 'second', name: 'Emmy', }, { id: 'third', name: 'Lazarus', } ]
let sorter = ['second', 'third', 'first']
const idMap = _.keyBy(myArray, 'id')
const result = _.map(sorter, x => idMap[x])
console.log(result)
<script src="/lodash.min.js"></script>
Это должно улучшиться, так как вы делаете только idMap once
а затем idMap once
access it by index
.
Если вы хотите отсортировать массив на месте, вам не нужен Lodash, вы можете легко сделать это с помощью ванильного JavaScript
let myArray = [
{
id: 'first',
name: 'john',
},
{
id: 'second',
name: 'Emmy',
},
{
id: 'third',
name: 'Lazarus',
}
]
let sorter = ['second', 'third', 'first']
//create a lookup table (map) to save looking through the array
const sortLookup = new Map();
//populate with element as key - index as value
sorter.forEach((id, index) => sortLookup.set(id, index));
//sort using the indexes of sorter
myArray.sort((a, b) => sortLookup.get(a.id) - sortLookup.get(b.id))
console.log(myArray)
Это использует карту, но ее можно легко выполнить с помощью обычного JavaScript-объекта {}
. Вам даже не нужно предварительно вычислять поиск myArray.sort((a, b) => sorter.indexOf(a.id) - sorter.indexOf(b.id))
, даст тот же самый результат, но он будет означает, что вместо того, чтобы перемещаться sorter
один раз для сложности O(n)
, вы потенциально имеете O(n^m)
или O(n^n)
(если оба массива имеют одинаковую длину)
sort
ведут себя по-разному от одного браузера к другому, что приводит к различным отсортированным массивам. Следовательно, использование lodash (или любого другого метода, не основанного на sort
) решит эту проблему.
compare(a, b)
-> 1 compare(b, a)
-> 0), это противоречиво, и вы нарушаете интерфейс сортировки. Единственная другая проблема заключается в том, что сортировка не обязательно является стабильной - вам нужны элементы, которые равны (по мнению компаратора), что вам все еще нужно в определенном порядке?