I have this array -
let array = [
{
"id": 123,
"pair": 312
},
{
"id": 321,
"pair": 111
},
{
"id": 312,
"pair": 123
},
{
"id": 111,
"pair": 321
}
];
And i need it to be sorted like this =
let array = [
{
"id": 123,
"pair": 312
},
{
"id": 312,
"pair": 123
},
{
"id": 321,
"pair": 111
},
{
"id": 111,
"pair": 321
}
];
Which means that i need to find the matched value of the pair key in the object, and put it right after the first element (eventually i need the to be sorted in pairs order - of course the array will be way bigger and mixed) i could not find a efficient way to achieve this.
this is what i tried - it feels very unefficient
products is the array i get from the server.
let pairs = [];
let prods = [...products];
for(let product of prods){
if(product.matched){
continue;
}
let pairStock = product.pairStock;
let companyId = product.company;
let matched = prods.filter(prod => prod.productId === pairStock && String(prod.company) === String(companyId));
if(matched.length > 0){
pairs.push(product);
pairs.push(matched[0]);
let index = prods.findIndex(prod => prod.productId === matched[0].productId);
prods[index].matched = true;
}
};
this will sort data when the number of items that are linked togather is between 0
and array.length
.
let products = [
{ productId: 'PK0154', pairStock: 'PK0112-02' },
{ productId: 'PK0112-02', pairStock: 'PK0154' },
{ productId: 'MGS-140', pairStock: 'MGS-136' },
{ productId: 'GM-0168', pairStock: 'GM-0169' },
{ productId: 'GM-0169', pairStock: 'GM-0168' },
{ productId: 'MGS-136', pairStock: 'MGS-140' },
]
function sort(data) {
var mappedArray = {}
data.forEach(obj => (mappedArray[obj.productId] = obj))
data.sort((a, b) => a.productId.localeCompare( b.productId) )
var addToRes = (res, id) => {
if (id !== undefined && mappedArray[id] !== undefined) {
var obj = mappedArray[id]
mappedArray[id] = undefined
res.push(obj)
addToRes(res, obj.pairStock)
}
}
var result = []
data.forEach(item => addToRes(result, item.productId))
return result
}
console.log(sort(products))
its results
0: {productId: "GM-0168", pairStock: "GM-0169"}
1: {productId: "GM-0169", pairStock: "GM-0168"}
2: {productId: "MGS-136", pairStock: "MGS-140"}
3: {productId: "MGS-140", pairStock: "MGS-136"}
4: {productId: "PK0112-02", pairStock: "PK0154"}
5: {productId: "PK0154", pairStock: "PK0112-02"}
The performant way (store a map of products and look up each product's pair by it's id) - O(n*2):
const productsObj = {};
products.forEach(product => productsObj[product.id] = product);
const [seenProducts, pairedProducts] = [{}, []];
products.forEach(product => {
const productPair = productsObj[product.pair);
if (!seenProducts[product.id]) pairedProducts.push(...[product, productPair])
seenProducts[productPair.id] = true;
});
console.log(pairedProducts)
The intuitive way O(n^2):
// Find the next pair if a pair doesn't already exist
const arr = [];
for (let i = 0; i < products.length; i++) {
const containsPair = arr.some(item => item.pair === products[i].id);
if (containsPair === false) {
const productPair = products.slice(i).find(({ id }) => id === item.pair));
arr.push(...[products[i], productPair]);
}
}
console.log(arr)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.