2

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.

5
  • 1
    Do you want to sort endArray based on order of order array ? Commented Oct 24, 2018 at 7:49
  • 1
    please add input and the wanted result. Commented Oct 24, 2018 at 7:50
  • I've updated the question. Commented Oct 24, 2018 at 7:54
  • why not you create array from object given ? 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. Commented Oct 24, 2018 at 7:58

5 Answers 5

3

You 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));
    }
}
Sign up to request clarification or add additional context in comments.

4 Comments

Since we have an array of primitives, I think is better to use indexOf method.
@MihaiAlexandru-Ionut, the order array contains objects, as i see it ...
Going to have to go with this one since it's super succinct and was the first one that worked. Thank-you.
You can even make a computed property: endArray() { return newObject.slice(0, 3).map(({ id }) => id); }
1

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));

Comments

1

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]',
    },
    computed: {
        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.net/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>

Comments

1

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);

Comments

-1
function compare(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(compare);

Looks like you're looking for the sort function on an array. Basically, you create a comparer and pass the function to the sort function.

In your situation, you would include logic to check/compare the values against the order array, in the comparer.

More info: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort

3 Comments

where did the last_nom variable in your answer came from? its not inside the question.
My bad, used an example I had available in an editor.
in your new example you seem to have confused the the contents of newArray and order, newArray is a list of numbers, orderis a list of objects containing a key-value pair: id: number

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.