Reputation: 175
I have an array like ['1','0', '3', 'a', 'b', 'z', 'xs', 'l', 'm', 'xl']
and a pattern array like ['m', 'l', 'xs', 'xl']
.
I need sort entered array first by pattern and other part of entered array by asc pattern.
The output I have to get is ['m', 'l', 'xs', 'xl', '0', '1', '3', 'a', 'b', 'z']
;
I'm implemented something like this
function sort(a, b) {
var mappattern = {'m': 1, 'l': 2, 'xs': 3, 'xl': 4}
if (mappattern[a.name] && mappattern[b.name]) {
return mappattern[a.name] - mappattern[b.name];
}
return -1
}
But this works incorrect
Upvotes: 1
Views: 89
Reputation: 908
You can sort by this way, using array index
var array = ['1','0', '3', 'a', 'b', 'z', 'xs', 'l', 'm', 'xl'];
array.sort(function (a, b) {
var pattern = ['m', 'l', 'xs', 'xl'];
var aIn = pattern.indexOf(a);
var bIn = pattern.indexOf(b);
if (aIn == bIn) {
return a.localeCompare(b);
}
if (aIn <= -1) {
return 1;
} else if (bIn <= -1) {
return -1;
} else {
return aIn - bIn;
}
});
document.write(JSON.stringify(array));
Upvotes: 0
Reputation: 386680
You could take a shorter approach by using values for sorting the pattern to top and a default value of zero which takes the other parts of conditions.
const
order = { m: -4, l: -3, xs: -2, xl: -1, default: 0 },
sort = (a, b) =>
(order[a] || order.default) - (order[b] || order.default) ||
a > b || -(a < b);
var array = ['1', '0', '3', 'a', 'b', 'z', 'xs', 'l', 'm', 'xl']
array.sort(sort);
console.log(...array);
Upvotes: 2
Reputation: 6067
At first i've separated the pattern items and others alphanumeric items from the input array. Then applied the normal sorted method. Here is the solution
const input = ["1", "0", "3", "a", "b", "z", "xs", "l", "m", "xl"];
const defaultPattern = ["m", "l", "xs", "xl"];
console.log(customSort(input, defaultPattern));
function customSort(inputArray = [], defaultPattern = []) {
// separating pattern and other array items
const inputObj = inputArray.reduce((acc, item) => {
if (defaultPattern.includes(item)) {
acc["pattern"] ? acc["pattern"].push(item) : (acc["pattern"] = [item]);
} else {
acc["others"] ? acc["others"].push(item) : (acc["others"] = [item]);
}
return acc;
}, {});
// Sorting
const inputPatterns = inputObj["pattern"];
inputPatterns.sort((a, b) => {
return defaultPattern.indexOf(a) - defaultPattern.indexOf(b);
});
const others = inputObj["others"].sort();
return [...inputPatterns, ...others];
}
Upvotes: 0
Reputation: 2426
To fix your approach, first - I don't know why you get name
property out of a string. Then, you have to sort elements within pattern (that part is now working), sort elements outside of pattern and sort between elements from each of those groups.
Here's a draft solution:
const mappattern = {
'm': 1,
'l': 2,
'xs': 3,
'xl': 4
};
function sort(a, b) {
if (mappattern[a] && mappattern[b]) {
return (mappattern[a] - mappattern[b]);
}
if (mappattern[a] && !mappattern[b]) {
return -1;
}
return a.localeCompare(b);
}
const res = ['1', '0', '3', 'a', 'b', 'z', 'xs', 'l', 'm', 'xl'].sort(sort);
document.write(JSON.stringify(res))
Upvotes: 0