Compare arrays or strings and return an array with all repeated elements (javascript)

Asked

Viewed 69 times

-1

I am using a function that returns a multidimensional array in which each index contains an array of prime factorization.
This function, in turn, can accept a variable amount of arguments and returns the mdc of how many numbers are passed as arguments.

Ex: mdc(60,100,150) returns an array mdcOperands = [ [2,2,3,5], [2,2,5,5], [2,3,5,5]];

I want to compare the different arrays within mdcOperands to return a new array with the mdcOperands[i][j] repeating at all. I tried to make a vis a vis comparison using a nested for loop but it compares only mdcOperands[i][j] with mdcOperands[i+1][j], but there are cases where this comparison does not return an element, but it may be that the mdcOperands[i][j] repeat itself in mdcOperands[i+1][j+2] for example, as in mdcOperands[0][3], mdcOperands[1][2] and mdcOperands [2][2].

I wanted to know if there is an easy way to compare these factored numbers arrays with i variable or if I could transform the results into strings and compare the repetition simultaneously in all strings, perhaps using a regex that accepts a variable as a match value, e.g.:

'2235'
'2255'
'2355'

and return '25', which I could turn into an array [2,5] and return to function mdc(60,100,150) = 2 * 5 = 10 (mdc dos três numeros). Remembering that the function mdc() that I defined accepts arguments from 1 up to the maximum possible.

Edit: Excerpt from Upado Comments.

function compareFactors(mdcOperands) {
  let comparingFactors = [].slice.call(arguments, 0);
  let mdcFactors = [];
  for (let mdcOperandsIndex = 0; mdcOperandsIndex < mdcOperands.length - 1; mdcOperandsIndex++) {
    for (let j = 0; j < mdcOperands[mdcOperandsIndex].length; j++) {
      if (mdcOperands[mdcOperandsIndex][j] === mdcOperands[mdcOperandsIndex + 1][j]) {
        mdcFactors.push(mdcOperands[mdcOperandsIndex][j])
      }
    }
  }
}
  • 2

    what have you tried to do to resolve? Post your code so we can help

  • Function compareFactors(mdcOperands) { //Let comparingFactors = [].slice.call(Arguments, 0); Let mdcFactors = []; for (Let mdcOperandsIndex = 0; mdcOperandsIndex < mdcOperands.length -1; mdcOperandsIndex++) { for (Let j = 0; j < mdcOperands[mdcOperandsIndex].length; j++) {&#xA; if (mdcOperands[mdcOperandsIndex][j] === mdcOperands[mdcOperandsIndex+1][j]) {&#xA; mdcFactors.push(mdcOperands[mdcOperandsIndex][j])&#xA; }&#xA; }&#xA; } }

  • It was bad, I started learning programming a little while ago and I don’t know how to use stackoverflow, I ended up here because I didn’t find anything anywhere, at least not with concepts that I know how to use to research. The closest I thought of this would be to turn it into strings and use Regex (which I have no idea how to operate) and do some kind of match between 2 strings WHILE variable, tpo str1.match(str2) but always returns null (I tried in the browser console).

  • Go straight to the point and you don’t have to explain that you’re a beginner. Format the text of the question with markdown. See [Ask], [help], Stack Overflow Survival Guide in English, Community FAQ and do our [tour].

  • Thanks @Augustovasques

  • I think you’re complicating something simple. See this example of function of the calculation of the mdc between n numbers.

Show 1 more comment

2 answers

1


You are unnecessarily complicating things. If you want to calculate MDC, you do not need to factor the numbers, there is a very simple algorithm for this:

// calcula o MDC entre dois números
function mdc2(a, b) {
    while (b != 0) {
        var r = a % b;
        a = b;
        b = r;
    }
    return a;
}

Of course, there are also recursive versions, since the mathematical definition is like this (MDC(a, b): if b for zero, a is the answer, otherwise the result is the MDC(b, a % b)), but I wouldn’t use recursion when the above iterative algorithm is much simpler (and also faster).

Then, to generalize to several numbers, it is enough to know that MDC(a, b, c) is equal to MDC(MDC(a, b), c). That is, just calculate the MDC of two in two numbers. It would look like this:

// calcula o MDC entre dois números
function mdc2(a, b) {
    while (b != 0) {
        var r = a % b;
        a = b;
        b = r;
    }
    return a;
}

function mdc(...numeros) { // calcula o MDC entre vários números
    if (numeros.length === 0) // não tem nenhum número
        return 0;
    if (numeros.length === 1) // só tem um número, ele próprio é o MDC
        return numeros[0];

    // calcula o MDC entre os dois primeiros números
    var result = mdc2(numeros[0], numeros[1]);
    // calcula o MDC deste com os restantes
    for (var i = 2; i < numeros.length; i++) {
        result = mdc2(result, numeros[i]);
    }
    return result;
}

console.log(mdc(60, 100, 150)); // 10


This is the simplest way to solve the main problem (find the MDC between several numbers).

But just for the record, if I were to find the elements in common between various arrays, I could do another answer, or how any of the options of this question, or with Set (which I believe is less worse, because a Set already is optimized not to allow repeated elements and so it is faster than processing arrays directly):

// calcula a intersecção entre dois sets
function intersect(s1, s2) {
    var result = new Set();
    for (var x of s1)
        if (s2.has(x))
            result.add(x);
    return result;
}

// calcula a intersecção entre todos os arrays
let mdcOperands = [[2, 2, 3, 5], [2, 2, 5, 5], [2, 3, 5, 5]];
let result = new Set(mdcOperands[0]);
for(var i = 1; i < mdcOperands.length; i++) {
    result = intersect(result, new Set(mdcOperands[i]));
}

// multiplica os elementos da intersecção
let mdc = 1;
for (var n of result) {
    mdc *= n;
}
console.log(mdc); // 10

But if the idea is just to compute the MDC between several numbers (and not necessarily "get elements in common between several arrays"), the first solution is the most suitable (because you don’t need to create several arrays or calculate the intersection between them).


When concatenating numbers and using regex, forget, it makes no sense. For example, if one of the arrays has [7, 19] and another has [719], in both cases, when joining the digits you will have 719. How will you differentiate? It is simpler to manipulate the numbers using the arrays themselves (or by converting them to Set, as done above).

  • Damn, I really messed up. I hadn’t really thought about this Regex issue, I still can’t use Regex and it really didn’t make sense anyway. Thank you very much!!!

  • I didn’t know that, I’ll accept it yes :)

0

In a general solution, to find the repeated items, you can turn this multidimensional array into a single array, since in this case (to find the repeated ones) the dimensions don’t matter.

let mdcOperands = [ [2,2,3,5], [2,2,5,5], [2,3,5,5]];
let flatOperands = mdcOperands.flat()
let repetidos = []
flatOperands.map(function(item,index){
  if((flatOperands.indexOf(item) !== index) && (repetidos.indexOf(item)=== -1)){
      repetidos.push(item)}
})

Here we use the method flat, to make a single array, with all elements of the sub arrays, then filter with the method map and using the if, the items that are repeated.

What the if is checking if the current item has the same current position, if this is true, means that it is the first appearance of it in the array, until then it is unique, otherwise it means that there is already a similar item in the array, then it is repeated.

The second check is whether this item is already in the repeater array (if the index return -1, is not), if not, the item is added to the repeat list.

This is a general solution, but how do you want to restrict the repetition to all arrays at the same time, we can make a kind of nested loops.

for (let i = 0;i<repetidos.length;i++){
  
  mdcOperands.map((item,index)=>{
    item.indexOf(repetidos[i]) === -1 ? repetidos.splice(i,1):''
  })
}

Here with the for, we take each repeated item and then submit it to a map of mdcOperands. It will go through each sub-list and a check will be done, if it is not in the current sub-list, it means it is not for us, since we want it to be in all sublists at the same time, if at least one he is not, we can exclude him, with the splice, that is removing the item from its current position. If it passes the test, nothing happens. Thus, only the array will remain, the items that go through each test, in all sublists. And finally, we have the return:

console.log(repetidos)//[2,5]

Browser other questions tagged

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