Reputation: 1043
I want to display the content of the buttons according to the alphabetical order and divide them in groups like A-H, I-Q and R-Z. My code is written in angular2+.
My array is -
this.dropdownList = [
{ item_text: 'Organisation' },
{ item_text: 'EwayBill' },
{ item_text: 'SAP' },
{ item_text: 'Collection' },
{ item_text: 'Cancel' },
{ item_text: 'Generate' },
{ item_text: 'Payments' },
{ item_text: 'SMS' },
{ item_text: 'Update' }
]
Upvotes: 0
Views: 914
Reputation: 1043
By manipulating the mentioned codes, i framed a code as such -
Proceed() {
// some basic interfaces to describe types
interface Item {
item_text: string;
}
interface LetterRange {
first: string;
last: string;
}
// the letter ranges
// this solution allows them to intersect
// can adjust for any letter ranges
const rangesAtoH: LetterRange[] = [
{first: 'a', last: 'h'},
];
const rangesItoQ: LetterRange[] = [
{first: 'i', last: 'q'},
];
const rangesRtoZ: LetterRange[] = [
{first: 'r', last: 'z'}
];
const dropdownParameter: Item[] = [
{ item_text: 'Organisation' },
{ item_text: 'EwayBill' },
{ item_text: 'SAP' },
{ item_text: 'Collection' },
{ item_text: 'Cancel' },
{ item_text: 'Generate' },
{ item_text: 'Payments' },
{ item_text: 'SMS' },
{ item_text: 'Update' }
];
// sort the words alphabetically so that they will appear in the right order
const sorted: Item[] = this.dropdownParameter.sort((a,b) => a.item_text.localeCompare(b.item_text));
console.log("inside Proceed, Sorted = ", sorted)
// -------------------------- Array 2 - suggestion-----------------------------
// array of grouped items (each group is array as well)
const grouped: Item[][] = sorted.reduce((groups, item) => {
const firstLetter: string = item.item_text.slice(0,1).toLowerCase();
console.log(firstLetter);
// run through each range and check whether the 'firstLetter' fits there
rangesAtoH.forEach((range, index) => {
if (firstLetter >= range.first.toLowerCase()
&& firstLetter <= range.last.toLowerCase()) {
groups[index].push(item);
}
});
return groups;
}, new Array(rangesAtoH.length).fill([])); // initialise with N empty arrays
console.log("grouped", grouped);
// ---letter range I to Q ------------------
const groupedItoQ: Item[][] = sorted.reduce((groups, item) => {
const firstLetter: string = item.item_text.slice(0,1).toLowerCase();
console.log(firstLetter);
// run through each range and check whether the 'firstLetter' fits there
rangesItoQ.forEach((range, index) => {
if (firstLetter >= range.first.toLowerCase()
&& firstLetter <= range.last.toLowerCase()) {
groups[index].push(item);
}
});
return groups;
}, new Array(rangesItoQ.length).fill([])); // initialise with N empty arrays
console.log("grouped I to Q = ", groupedItoQ);
// ---letter range R to Z ------------------
const groupedRtoZ: Item[][] = sorted.reduce((groups, item) => {
const firstLetter: string = item.item_text.slice(0,1).toLowerCase();
console.log(firstLetter);
// run through each range and check whether the 'firstLetter' fits there
rangesRtoZ.forEach((range, index) => {
if (firstLetter >= range.first.toLowerCase()
&& firstLetter <= range.last.toLowerCase()) {
groups[index].push(item);
}
});
return groups;
}, new Array(rangesRtoZ.length).fill([])); // initialise with N empty arrays
console.log("grouped I to Q = ", groupedRtoZ);
}
Upvotes: 0
Reputation: 2883
This is the solution I came up with. Can be optimised for the cases when we know that the letter ranges don't intersect.
// some basic interfaces to describe types
interface Item {
item_text: string;
}
interface LetterRange {
first: string;
last: string;
}
// the letter ranges
// this solution allows them to intersect
// can adjust for any letter ranges
const ranges: LetterRange[] = [
{first: 'a', last: 'h'},
{first: 'i', last: 'q'},
{first: 'r', last: 'z'}
];
const dropdownList: Item[] = [
{ item_text: 'Organisation' },
{ item_text: 'EwayBill' },
{ item_text: 'SAP' },
{ item_text: 'Collection' },
{ item_text: 'Cancel' },
{ item_text: 'Generate' },
{ item_text: 'Payments' },
{ item_text: 'SMS' },
{ item_text: 'Update' }
];
// sort the words alphabetically so that they will appear in the right order
const sorted: Item[] = dropdownList.sort((a,b) => a.item_text.localeCompare(b.item_text));
// array of grouped items (each group is array as well)
const grouped: Item[][] = sorted.reduce((groups, item) => {
const firstLetter: string = item.item_text.slice(0,1).toLowerCase();
console.log(firstLetter);
// run through each range and check whether the 'firstLetter' fits there
ranges.forEach((range, index) => {
if (firstLetter >= range.first.toLowerCase()
&& firstLetter <= range.last.toLowerCase()) {
groups[index].push(item);
}
});
return groups;
}, new Array(ranges.length).fill([])); // initialise with N empty arrays
console.log(grouped);
/*
[
[ { item_text: 'Cancel' },
{ item_text: 'Collection' },
{ item_text: 'EwayBill' },
{ item_text: 'Generate' }
],
[
{ item_text: 'Organisation' },
{ item_text: 'Payments' }
],
[ { item_text: 'SAP' },
{ item_text: 'SMS' },
{ item_text: 'Update' }
]
]
*/
Upvotes: 2
Reputation: 754
Sort it with a compare function https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort
dropdownList.sort(function (item1, item2) {
if (item1.item_text < item2.item_text)
return -1;
if ( item1.item_text > item2.item_text)
return 1;
return 0;
})
or more simple:
dropdownList.sort(function (item1, item2) {
return ('' + item1.item_text).localeCompare(item2.item_text);
})
This is copy pasted with changes from https://stackoverflow.com/a/51169/7329611 with credits to Shog9
After sorting you can slice the array into groups with the slice function https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/slice After sorting you should find the indexes of the first occurance of objects with the next higher alphabetical character and set these indexes as slice(from, to) So for the first step you have to find the first element with next higher Character wich in your case is 'i' since its follows 'h'
let breakpoint = dropdownList.find(function(element) {
return element.item_text.charAt(0).toLowerCase() === 'i';
})
Next you can slice the original array at
let slicePoint = dropdownList.indexOf(breakpoint)-1
dropdownList.slice(slicePoint);
Ofcourse this requires the array to contain at least one element with 'i' at start.
Upvotes: 1