Ramda действительно сияет для этих проблем.
Если размер данных невелик, мы можем использовать простую функцию reduce и вспомогательный помощник indexOf.
// match id of object to required index and insert
var sortInsert = function (acc, cur) {
var toIdx = R.indexOf(cur.id, a);
acc[toIdx] = cur;
return acc;
};
// point-free sort function created
var sort = R.reduce(sortInsert, []);
// execute it now, or later as required
sort(b);
// [ { id: 2 }, { id: 3 }, { id: 1 }, { id: 4 } ]
Это хорошо работает для небольших (ISH) наборов данных, но indexOf операции на каждой итерации за счет сокращения неэффективно для больших наборов данных.
Мы можем исправить это, зайдя на проблему с другой стороны, давайте сможем использовать groupBy, чтобы сгруппировать наши объекты по их идентификатору, создав таким образом поиск по словарю (намного лучше!). Затем мы можем просто map по необходимым индексам и преобразовать их в соответствующий объект в этой позиции.
А вот решение с использованием этого подхода:
var groupById = R.groupBy(R.prop('id'), b);
var sort = R.map(function (id) {
return groupById[id][0];
});
sort(a);
// [ { id: 2 }, { id: 3 }, { id: 1 }, { id: 4 } ]
Наконец, это еще одно решение, которое является очень емким:
R.sortBy(R.pipe(R.prop('id'), R.indexOf(R.__, a)))(b);
// [ { id: 2 }, { id: 3 }, { id: 1 }, { id: 4 } ]
Я люблю то, как вы можете сочинить функции с поведением и отделить алгоритм от данных, на которых он действует, используя Ramda. Вы получаете очень читаемый и простой в обслуживании код.
Действительно ли реальные объекты 'b' содержат что-либо иное, чем просто' id'? – georg