Reputation: 81
I have an array like:
let arr = [
{
label: "abc",
value: 2,
checked: true
},
{
label: "bcd",
value: 1,
checked: true
},
{
label: "cde",
value: 4,
checked: false
},{
label: "def",
value: 6,
checked: true
},
{
label: "efg",
value: 3,
checked: false
},
{
label: "fgh",
value: 5,
checked: true
}
]
I'm trying to sort this in two different ways ( alphabetically, by value ). The current implementation of the sort works properly, but I'm running into some issues when I'm sorting by value... How can I obtain an array of these values from 'arr' sorted descending by value only when the checked flag is true? I mean... I want to sort by value only the elements that are checked and for the rest of the elements to preserve them as they are at the initial index...
//expected result
let arr = [
{ //sorted index 0
label: "bcd",
value: 1,
checked: true
},
{ //sorted index 1
label: "abc",
value: 2,
checked: true
},
{ //checked: false - perserve index (2) from the initial array
label: "cde",
value: 4,
checked: false
},
{ //sorted index 3
label: "fgh",
value: 5,
checked: true
},
{ //checked: false - perserve index (4) from the initial array
label: "efg",
value: 3,
checked: false
},
{ //sorted index 5
label: "def",
value: 6,
checked: true
}
]
Is there a simple way to use lodash? Or is it needed to do it manually, and how?
Upvotes: 0
Views: 84
Reputation: 4519
I know I am late but here is a different appreach using bubbling
for(let i=0;i<arr1.length-1;i++){
for(let j=0;j<arr1.length-i-1;j++){
if(arr1[j].checked==true){
if(arr1[j].value>arr1[j+1].value){
v=arr1[j]
arr1[j]=arr1[j+1]
arr1[j+1]=v
}
}
}
}
Upvotes: 0
Reputation: 4226
This solution works by copying the checked items into a separate array, sorting them, then reinserting them into (a copy of) the original array.
const
// Gets the original array
arr = getArr()
// Defines a function to use for sorting
compare = (a, b) => a.value - b.value,
// Makes an array of just the objects where `.checked` is truthy, and sorts it
partSorted = arr
.filter(obj => obj.checked)
.sort(compare);
// Defines a variable to track the index within the `partSorted` array
let i = 0;
// Copies `arr`, but substitutes the next item from `partSorted` if appropriate
const sorted = arr.map(obj =>
obj.checked ? partSorted[i++] : obj
);
// Shows the result
console.log(sorted);
// Defines the original array
function getArr(){
return [
{ label: "abc", value: 2, checked: true },
{ label: "bcd", value: 1, checked: true },
{ label: "cde", value: 4, checked: false },
{ label: "def", value: 6, checked: true },
{ label: "efg", value: 3, checked: false },
{ label: "fgh", value: 5, checked: true }
];
}
Upvotes: 2
Reputation: 386550
You could store the indices to put the sorted values back and take the objects for sorting. Sort and apply back.
var array = [{ label: "abc", value: 2, checked: true }, { label: "bcd", value: 1, checked: true }, { label: "cde", value: 4, checked: false }, { label: "def", value: 6, checked: true }, { label: "efg", value: 3, checked: false }, { label: "fgh", value: 5, checked: true }],
indices = [];
array
.filter(({ checked }, i) => checked && indices.push(i))
.sort(({ value: a }, { value: b }) => a - b)
.forEach((v, i) => array[indices[i]] = v);
console.log(array);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Upvotes: 2
Reputation: 162
You can use native JavaScript sort. 1 and -1 changes the sort position, 0 will keep the order.
If it is reversed then change a
with b
.
arr.sort((a, b) => a.checked ? b.value - a.value : 0);
Upvotes: 0