Sort an Array According to the Elements of Another Array

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



Leave a reply



Submit