Given an array like this:
var endArray = [34, 35, 32]
And an object like this:
var order = [{"id":35},{"id":34},{"id":32},{"id":30},{"id":28},{"id":24},{"id":17},{"id":15},{"id":3}]
How can I re-sort endArray
when order
is changed? I'm working in Vue so I can write a watcher like so:
watch: {
order: function (newObject) {
// resort endArray here somehow
}
}
But I'm not sure how to map the order to sort endArray
.
Update
Expected result is:
endArray = [35, 34, 32]
To match the order of id
keys set in order
.
Given an array like this:
var endArray = [34, 35, 32]
And an object like this:
var order = [{"id":35},{"id":34},{"id":32},{"id":30},{"id":28},{"id":24},{"id":17},{"id":15},{"id":3}]
How can I re-sort endArray
when order
is changed? I'm working in Vue so I can write a watcher like so:
watch: {
order: function (newObject) {
// resort endArray here somehow
}
}
But I'm not sure how to map the order to sort endArray
.
Update
Expected result is:
endArray = [35, 34, 32]
To match the order of id
keys set in order
.
-
1
Do you want to sort
endArray
based on order oforder
array ? – Mihai Alexandru-Ionut Commented Oct 24, 2018 at 7:49 - 1 please add input and the wanted result. – Nina Scholz Commented Oct 24, 2018 at 7:50
- I've updated the question. – t56k Commented Oct 24, 2018 at 7:54
- why not you create array from object given ? – Niklesh Raut Commented Oct 24, 2018 at 7:56
- There are other factors at play beyond how I've simplified the problem for SO, i..e, the array controls the IDs selected, the object controls the order. – t56k Commented Oct 24, 2018 at 7:58
5 Answers
Reset to default 3You could slice the array for getting the first three objects and map id
.
watch: {
order: function (newObject) {
endArray = newObject.slice(0, 3).map(({ id }) => id);
}
}
A different solution could be to sort the array.
watch: {
order: function (newObject) {
const getIndex = id => newObject.findIndex(o => o.id === id);
endArray.sort((a, b) => getIndex(a) - getIndex(b));
}
}
Make an array to find ids and split it by length of given array/OR direct provide length if known here 3
.
var endArray = [34, 35, 32];
var order = [{"id":35},{"id":34},{"id":32},{"id":30},{"id":28},{"id":24},{"id":17},{"id":15},{"id":3}];
var orderIds = order.map(function(e){return e.id});
console.log(orderIds.splice(0,endArray.length));
The way to solve this problem is to divide the problem in steps:
Since you want to sort the array, you want to call endArray.sort((a, b) => {})
On what do you want to sort? The index where the idcould be found:
endArray.sort((a, b) => {
let indexA;
for(indexA = 0; indexA < this.order.length; indexA++) {
if (this.order[indexA].id === a) break;
}
let indexB;
for(indexB = 0; indexB < this.order.length; indexB++) {
if (this.order[indexB].id === b) break;
}
// ...
})
How do we want to sort it? ascending:
endArray.sort((a, b) => {
let indexA;
for(indexA = 0; indexA < this.order.length; indexA++) {
if (this.order[indexA].id === a) break;
}
let indexB;
for(indexB = 0; indexB < this.order.length; indexB++) {
if (this.order[indexB].id === b) break;
}
if (indexA > indexB) return 1;
if (indexB > indexA) return -1;
return 0;
})
When do we want to sort it? When order
or newArray
changes:
new Vue({
el: '#app',
data: {
orderString: '[{"id":35},{"id":34},{"id":32},{"id":30},{"id":28},{"id":24},{"id":17},{"id":15},{"id":3}]',
newArrayString: '[34, 35, 32]',
},
puted: {
order() {
return JSON.parse(this.orderString);
},
newArray() {
return JSON.parse(this.newArrayString);
},
result() {
// Make a copy to prevent editing the original data
return [...this.newArray].sort((a, b) => {
let indexA;
for(indexA = 0; indexA < this.order.length; indexA++) {
if (this.order[indexA].id === a) break;
}
let indexB;
for(indexB = 0; indexB < this.order.length; indexB++) {
if (this.order[indexB].id === b) break;
}
if (indexA > indexB) return 1;
if (indexB > indexA) return -1;
return 0;
})
}
},
})
<!-- development version, includes helpful console warnings -->
<script src="https://cdn.jsdelivr/npm/vue/dist/vue.js"></script>
<div id="app">
<p>
Order:
<textarea v-model="orderString"></textarea>
</p>
<p>
NewArray:
<textarea v-model="newArrayString"></textarea>
</p>
<p>
Result:
{{ result }}
</p>
</div>
Just use sort
method by passing a callback
provided function. I used indexOf
function in order to find the index
of a specified element
.
var endArray = [34, 35, 32]
var order = [{"id":35},{"id":34},{"id":32},{"id":30},{"id":28},{"id":24},{"id":17},{"id":15},{"id":3}]
var orderIds = order.map(({id}) => id);
endArray.sort((a,b) => orderIds.indexOf(a) - orderIds.indexOf(b));
console.log(endArray);
function pare(a,b) {
if (order.indexOf(a.id) > order.indexOf(b.id))
return -1;
if (order.indexOf(a.id) < order.indexOf(b.id))
return 1;
return 0;
}
endArray.sort(pare);
Looks like you're looking for the sort function on an array. Basically, you create a parer and pass the function to the sort function.
In your situation, you would include logic to check/pare the values against the order array, in the parer.
More info: https://developer.mozilla/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort