How to sort a vector (A) according to another vertor (B) (containing repeated numbers) in javascript?

Asked

Viewed 77 times

1

problematic: I have a table with questions, For each type of Intervention I carry certain questions. I need to show these questions on a completion screen, for this type of specific intervention. What defines the sequence of questions is the type of intervention.

Example: BENCH:

  • questions: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10.

Questions by intervention:

  • Intervened1: 2, 3, 5, 9, 10.
  • Intervener 2: 1, 9, 1, 2, 1, 3, 4.
  • Intervener 3: 5, 6, 9, 4, 2, 1.

The problem is that the questions are shown as well, according to the answer. I can have in an Intervention, which starts with question 1, if the user answers YES, loads questions 2, 3, 5. If he answers NO, loads questions 9, 8, 5, 2.

And I may have repeated questions for the same intervention. As in the example of the Code. But for this same question, the user can have different answers. And in the conclusion, the question related to the answer must appear correctly. In the order.


I have the following code:

let intervencao = [{id:1},{id:5},{id:6},{id:7},{id:8},{id:9},{id:10},{id:11},{id:12},{id:12},{id:12},{id:12},{id:12},{id:12},{id:12},{id:13},{id:14},{id:15},{id:16},{id:17},{id:18},{id:19},{id:20},{id:21},{id:22},{id:23},{id:24},{id:25},{id:26}];
    
    function sortIntervencao(dados) {
    	let sort = [];
       
    	intervencao.forEach(p => {
    		sort[dados.findIndex(x => x === p.id)] = p;
    	});
    		return sort;
    }
        
    let dados = [1,5,6,7,8,9,10,11,12,13,14,12,15,16,12,17,18,12,19,20,12,21,22,12,23,24,12,25,26];
    
    let sortDados = sortIntervencao(dados);
    console.log(sortDados);

I need the intervention object to be ordered according to the given object.

note, that data has several "12" repeated in the course of the vector.

I need the Intervention to stay the same.

But when I run the code, the first "12" is right, the others are gone.

inserir a descrição da imagem aqui

Another problem is that this intervention will not always have all the fields.

For example:

let intervencao = [{id:1},{id:6},{id:7},{id:8},{id:9},{id:10},{id:11},{id:12},{id:12},{id:12},{id:12},{id:12},{id:12},{id:13},{id:14},{id:15},{id:16},{id:17},{id:21},{id:22},{id:23},{id:24},{id:25},{id:26}];
    
    function sortIntervencao(dados) {
    	let sort = [];
       
    	intervencao.forEach(p => {
    		sort[dados.findIndex(x => x === p.id)] = p;
    	});
    		return sort;
    }
        
    let dados = [1,5,6,7,8,9,10,11,12,13,14,12,15,16,12,17,18,12,19,20,12,21,22,12,23,24,12,25,26];
    
    let sortDados = sortIntervencao(dados);
    console.log(sortDados);

so it cannot be an exact copy. as per that answer here!

See it running here: code

  • The code in jsFiddle is not working. Change this line altert(sortDados.foreach(x => x.id)); for sortDados.forEach(x => console.log(x));.

  • 1

    The problem is that dados.findIndex(x => x === p.id) will always find the same index for Sort when p.id is equal. So, for example, for the object {id:12} in position intervencao[9], the dados.findIndex will return 8, and will put this object on sort[8]; but for {id:12} in intervencao[10], dados.findIndex will return 8 again, and will then overlay the object in Sort[8]. You can see well this by placing this line console.log(p, dados.findIndex(x => x === p.id)); in the intervencaoforEach().

  • Yes, you can see this exactly in the second code, when the field does not have it. It puts the blank space. But, how to solve this? I can make a condition?

  • 1

    What condition? What are the other attributes of the objects? What defines what intervention[9] should be on Sort[8], and intervention[10] on Sort[11]? You’d have to ask the question what real problem you’re trying to solve.

  • updated the question, with the problem as a whole.

  • unfortunately I still do not understand the relationship of the code with the question. intervencao, in the code would be a roadmap for a type of intervention? dados would be a real intervention, with the questions asked according to the user’s answers? But in this case, why would there be repeated questions in the intervention (12 - have you ever tried to turn it on and off? 12 - have you ever tried to turn it on and off?)? And why order intervention instead of for each data item seeking the corresponding intervention? Anyway, see my answer.

  • I’m going to implement it here, and run some tests. But I think your solution solved the problem. I’m going to test it here. And I mark it as an answer. Thank you. :)

Show 2 more comments

1 answer

1


One solution is to maintain an array with the last found index for an id, and using the function indexOf() search from that last index instead of always from the beginning of the array:

function sortIntervencao(dados) {
    let sort = [];
  let idxs = [];

    intervencao.forEach(p => {
    let id = p.id;
    let start = idxs[id] ? idxs[id] + 1 : 0;
    let idx = dados.indexOf(id, start);
    console.log(p, idx);
        sort[idx] = p;
    idxs[id] = idx;
    });
        return sort;
}

See working here.

Note: this is a solution to the abstract problem presented. Depending on the real problem, there may be a more appropriate solution.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.