Reputation: 61
I want to sort Below array based on name
,receiver_id
,sender_id
and role_id
this.role_id = 3
this.Data = [
{receiver_id: 3,sender_id:4,name: 'john',},
{receiver_id: 4,sender_id:3,name: 'james'},
{receiver_id: 2,sender_id:3,name: 'jane'},
{receiver_id: null,sender_id:null,name: 'charles'},
{receiver_id: null,sender_id:null,name: 'aaron'},
{receiver_id: 2,sender_id:4,name: 'alex'},
{receiver_id: 3,sender_id:2,name: 'david'},
];
I want array objects with receiver_id == role_id
or sender_id == role_id
to be on top of array and also it should be in alphabetical order. like this
this.Data = [
{receiver_id: 3,sender_id:2,name: 'david'},
{receiver_id: 4,sender_id:3,name: 'james'},
{receiver_id: 2,sender_id:3,name: 'jane'},
{receiver_id: 3,sender_id:4,name: 'john'},
{receiver_id: null,sender_id:null,name: 'aaron'},
{receiver_id: 2,sender_id:4,name: 'alex'},
{receiver_id: null,sender_id:null,name: 'charles'},
];
as of now I can sort based on name only
let colName = 'name'
this.Data.sort((b, a) => a[colName] < b[colName] ? 1 : a[colName] > b[colName] ? -1 : 0)
how to do this?
Upvotes: 0
Views: 896
Reputation: 1
You can first sort them after thier "sender_id" and then iterrate over them and sort Alphabetically. Note that the code below is not perfect an can probably writtern more efficent.
Example:
function sort(array) {
// returns function if array is undefined or empty
if(!array) return;
let finalList = [];
let swapped = false;
do {
swapped = false;
for(let i = array.length - 1; i > 0; i--) {
if(array[i].sender_id < array[i - 1].sender_id) {
let temp = array[i];
array[i] = array[i - 1];
array[i - 1] = temp;
swapped = true;
}
}
} while (swapped);
// sorts alphabetic
let lastBucket = [];
let lastId = 1;
for(entry in array) {
if(array[entry].sender_id > lastId) {
lastId = array[entry].sender_id;
let swapped = false;
do {
swapped = false;
for(let i = lastBucket.length - 1; i > 0; i--) {
if(lastBucket[i].name < lastBucket[i - 1].name) {
let temp = lastBucket[i];
lastBucket[i] = lastBucket[i - 1];
lastBucket[i - 1] = temp;
swapped = true;
}
}
for (item in lastBucket) {
finalList.push(lastBucket[item]);
}
lastBucket = [];
} while(swapped);
}
lastBucket.push(array[entry]);
}
for(item in lastBucket) {
finalList.push(lastBucket[item]);
}
return finalList;
}
// Test data
const sampleArray = [
{
sender_id: 1,
name: "test"
},
{
sender_id: 3,
name: "abc"
},
{
sender_id: 2,
name: "acd"
},
{
sender_id: 1,
name: "qqqqq"
},
{
sender_id: 9,
name: "hello world"
},
{
sender_id: 1,
name: "abc"
}
]
let sorted = sort(sampleArray);
Upvotes: 0
Reputation: 62676
It might help to factor the conditions into functions. vip
means the object satisfies the numerical test. The other key idea is that vip sameness defaults to the alpha sort. This way we get the alpha sort amongst both vips and non-vips.
let role_id = 3
let data = [
{receiver_id: 3,sender_id:4,name: 'john',},
{receiver_id: 4,sender_id:3,name: 'james'},
{receiver_id: 2,sender_id:3,name: 'jane'},
{receiver_id: 2,sender_id:4,name: 'alex'},
{receiver_id: 3,sender_id:2,name: 'david'},
];
function diff(a, b) {
const vip = obj => (role_id === obj.receiver_id) || (role_id === obj.sender_id)
const vipA = vip(a), vipB = vip(b)
return vipA === vipB ? a.name.localeCompare(b.name) : (vipA ? -1 : 1)
}
console.log(data.sort(diff))
Upvotes: 1
Reputation: 215
You could try something like this:
this.Data.filter(a => (a.receiver_id === 3 || a.sender_id === 3))
.sort((b, a) => a.name < b.name ? 1 : a.name > b.name ? -1 : 0)
.concat(
this.Data.filter(a => !(a.receiver_id === 3 || a.sender_id === 3))
.sort((b, a) => a.name < b.name ? 1 : a.name > b.name ? -1 : 0))
First, we filter only those entries which satisfy the condition receiver_id == role_id || sender_id == role_id
, then we sort them by name.
We do the same for those entries which do not satisfy the condition. And finally we concatenate the two resulting arrays.
Upvotes: 0
Reputation: 476
With the sort method you determine if an item A goes before or after the other (B). First you need to define priorities, based on your description I guess:
1º: items where receiver_id == role_id || sender_id == role_id, ordered alphabetically
2º: items where receiver_id != role_id && sender_id != role_id, ordered alphabetically
That would be:
this.Data.sort( (a, b) => {
let conditionForA = a.receiver_id == role_id || a.sender_id == role_id;
let conditionForB = b.receiver_id == role_id || b.sender_id == role_id;
if (conditionForA && !conditionForB) {
// A > B
return 1;
}
if (conditionForB && !conditionForA) {
// B > A
return -1;
}
// For now A = B, let's compare alphabetically
if (a.name > b.name) return 1;
else if (a.name < b.name) return -1;
return 0; //equal
});
Upvotes: 0