Javascript - sort array based on another array
One-Line answer.
itemsArray.sort(function(a, b){
return sortingArr.indexOf(a) - sortingArr.indexOf(b);
});
Or even shorter:
itemsArray.sort((a, b) => sortingArr.indexOf(a) - sortingArr.indexOf(b));
How to sort one array based on another array using Ruby
It perfectly works:
▶ A = [1,3,2,6,4,5,7,8,9,10]
▶ B = [3,4,1,5,2,6]
▶ B.sort_by &A.method(:index)
#⇒ [1, 3, 2, 6, 4, 5]
If there could be elements in B
that are not present in A
, use this:
▶ B.sort_by { |e| A.index(e) || Float::INFINITY }
Sort an array according to the elements of another array
hash_object = objects.each_with_object({}) do |obj, hash|
hash[obj.object_id] = obj
end
[1, 2, 3, 4, 5].map { |index| hash_object[index] }
#=> array of objects in id's order
I believe that the run time will be O(n)
Sort an array according to the sequence of another array
If I understand your question correctly, you want to calculate the inverse of the sorted permutation of B
, and then order sorted A
in that order. You can do this pretty easily with the standard library.
int A[] = { 8, 9, 11, 14, 16, 20};
int B[] = { 6, 5, 1, 2, 4, 3};
const auto ASIZE = std::extent<decltype(A)>::value;
const auto BSIZE = std::extent<decltype(B)>::value;
// A and B must be the same size
assert(ASIZE == BSIZE);
// p = sorted permutation of B largest to smallest
std::vector<size_t> p(ASIZE);
std::iota(p.begin(), p.end(), 0);
std::sort(p.begin(), p.end(), [&](size_t i1, size_t i2) { return B[i1] > B[i2]; });
// pinv = inverse of p
std::vector<size_t> pinv(ASIZE);
for (size_t i = 0; i < ASIZE; ++i)
pinv[p[i]] = i;
// Sort A largest to smallest
std::sort(std::begin(A), std::end(A), [&](int v1, int v2) { return v1 > v2; });
Then you can indirect through pinv
to get A
in the order you want.
for (size_t index : pinv)
std::cout << A[index] << " ";
std::cout << std::endl;
// Output is: 20 16 8 9 14 11
Sort array based on the order from another array Swift
You can try the following in Swift. Note the dictionaries in Swift are unordered so you have to use arrays for ordered collections:
let fetchedProducts = [
(name: "productName20", id: 20),
(name: "productName3", id: 3),
(name: "productName1", id: 1),
]
let sortedProducts = [
("productName1", "1"),
("productName20", "20"),
("productName3", "3"),
]
let sortedFetchedProducts = sortedProducts
.compactMap { s in
fetchedProducts.first(where: { s.1 == String($0.id) })
}
print(sortedFetchedProducts)
// [(name: "productName1", id: 1), (name: "productName20", id: 20), (name: "productName3", id: 3)]
Sort array of objects based on another array and move items not in that array to the end
I'd start by building a complete array
to perform the sort, including missing elements from the keys, in their original order...
var arrayObject = [{key: 'g'},{key: 'a'},{key: 'b'},{key: 'c'},{key: 'd'},{key: 'e'}];
var array = ['a', 'c', 'd', 'e'];
arrayObject.forEach(o => { if (!array.includes(o.key)) array.push(o.key)})
// now your code works fine let result = arrayObject.sort((a, b) => { return array.indexOf(a.key) - array.indexOf(b.key); });
console.log(result)
Javascript sort array of objects based on another array
that ?
const arr1 =
[ { id: 21, name: 'Joey', vehicle: 'car' }
, { id: 6, name: 'Kevin', vehicle: 'car' }
, { id: 10, name: 'Luis', vehicle: 'van' }
]
const arr2 =
[ { id: 6, name: 'Kevin' }
, { id: 21, name: 'Joey' }
, { id: 10, name: 'Luis' }
]
// Arr1 ordered..
const arr1_ord = arr2.map(a2=> arr1.find(x=>x.id===a2.id))
console.log( arr1_ord )
.as-console-wrapper {max-height: 100%!important;top:0}
Sort an array of arrays based on the order in another array
h = x.to_h
# => {"ready"=>5,
# "shipped"=>1,
# "pending"=>1,
# "refunded"=>1,
# "delivered"=>23,
# "scheduled"=>1,
# "canceled"=>51}
order_array.map{|key| [key, h[key]] if h.key?(key)}.compact
# => [["ready", 5],
# ["shipped", 1],
# ["scheduled", 1],
# ["delivered", 23],
# ["canceled", 51],
# ["refunded", 1]]
or
h = x.to_h{|k, v| [k, [k, v]]}
#=> {"ready"=>["ready", 5],
# "shipped"=>["shipped", 1],
# "pending"=>["pending", 1],
# "refunded"=>["refunded", 1],
# "delivered"=>["delivered", 23],
# "scheduled"=>["scheduled", 1],
# "canceled"=>["canceled", 51]}
order_array.map{|k| h[k]}.compact
#=> [["ready", 5],
# ["shipped", 1],
# ["scheduled", 1],
# ["delivered", 23],
# ["canceled", 51],
# ["refunded", 1]]
or
h = x.to_h{|k, v| [k, [k, v]]}
#=> {"ready"=>["ready", 5],
# "shipped"=>["shipped", 1],
# "pending"=>["pending", 1],
# "refunded"=>["refunded", 1],
# "delivered"=>["delivered", 23],
# "scheduled"=>["scheduled", 1],
# "canceled"=>["canceled", 51]}
h.values_at(*order_array).compact
#=> [["ready", 5],
# ["shipped", 1],
# ["scheduled", 1],
# ["delivered", 23],
# ["canceled", 51],
# ["refunded", 1]]
Sort an array based on another array element’s class
I think this works:
arry.sort_by{ |v|
order.map{ |c|
v.is_a?(Object.const_get(c)) ? -1 : 1
}
}
# ["Hello", "World", 1, 2, 3, 4, 5, 34, nil, nil, true, false]
Object.const_get(c)
converts the string to class.
Sort an array of objects based on another array of ids
Ramda really shines for these types of problems.
Where the size of the data is small, we can use a simple reduce function, and indexOf helper.
// 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 } ]
This works well for small(ish) data sets but the indexOf operation on every iteration through the reduction is inefficient for large data sets.
We can remedy this by tackling the problem from the other side, lets use groupBy to group our objects by their id, thus creating a dictionary lookup (much better!). We can then simply map over the required indexes and transform them to their corresponding object at that position.
And here is the solution using this approach:
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 } ]
Finally, this is yet another solution, which is very succinct:
R.sortBy(R.pipe(R.prop('id'), R.indexOf(R.__, a)))(b);
// [ { id: 2 }, { id: 3 }, { id: 1 }, { id: 4 } ]
I love the way you can compose functions with behaviour and separate the algorithm from the data upon which it acts using Ramda. You end up with very readable, and easy to maintain code.
Related Topics
Ruby Style: How to Check Whether a Nested Hash Element Exists
Optional Argument After Splat Argument
How to Make a Http Request Using Ruby on Rails
The 'Json' Native Gem Requires Installed Build Tools
How to Specify a Local Gem in My Gemfile
Pass Variables to Ruby Script Via Command Line
Why Does Ruby Have Both Private and Protected Methods
Measure the Distance Between Two Strings With Ruby
Cannot Install Json Gem in Rails Using Windows
Printing the Source Code of a Ruby Block
Is the Ruby Operator ||= Intelligent
Error When Running Rails App - Execjs::Runtimeerror