Function that returns an array of strings that are in all arrays

Asked

Viewed 81 times

4

Talk people, all good?

My doubt is simple, but the solution may not be so simple.

The truth is that I am doing a job in JS and soon I will need to solve a problem that will make me spend a few hours cracking my head.

So I decided to ask here at Stackoverflow to advance a little of the solution.

Let’s go to problematic.

Suppose I have declared 5 arrays, follow:

var objetos = ["abridor de garrafa", "abridor de latas", "adaga", "ábaco", "abajur", "abotoadura", "acetona", "açucareiro", "zabumba", "xícara", "zarabatana", "xilofone"];
var redondos = ["ábaco", "abajur", "abotoadura", "acetona", "açucareiro", "zabumba", "xícara"];
var cozinha = ["abridor de garrafa", "abridor de latas", "açucareiro", "xícara"];
var arma = ["adaga", "zarabatana"];
var musical = ["xilofone", "zabumba"]

Now, I need a function that when I pass 2 (or more) arrays, it returns me a new array, containing only the strings that are present in ALL arrays that I have passed.

Exemplifying:

If I pass to the function the arrays: "objects", "round" and "musical", the new array I receive, should contain only "zabumba".

  • 1

    Strange that it makes it seem like you want us to do your job so you don’t have to do it when it’s necessary. The solution is pretty simple too, so I’ll wait for you to first try to do it to only then help you.

  • @Andersoncarloswoss I understand your vision, but it’s just that this is a very small part of something bigger that I’m doing and that I know it’s going to take a little while to find the most optimized solution, this inclusive, is another point that makes me come here to ask the staff and see the solutions and discuss, until arriving at a more optimized.

  • 1

    I also understand you and, particularly, these are the discussions that I like most here, but without you trying to do something that would just be us arguing and you hoping for the best solution, right? And from personal experience, this time that you think it will take to arrive at a solution will be exactly the time that will make you understand the solution. Tip for when to try: think simple and do the simple.

2 answers

3


Good people, follow the solution of the problem:

var objetos = ["abridor de garrafa", "abridor de latas", "adaga", "ábaco", "abajur", "abotoadura", "acetona", "açucareiro", "zabumba", "xícara", "zarabatana", "xilofone"];
var redondos = ["ábaco", "abajur", "abotoadura", "acetona", "açucareiro", "zabumba", "xícara"];
var cozinha = ["abridor de garrafa", "abridor de latas", "açucareiro", "xícara"];
var arma = ["adaga", "zarabatana"];
var musical = ["xilofone", "zabumba"]

var arrays = [objetos, redondos, musical];

var result = arrays.shift().filter(function(v) {
    return arrays.every(function(a) {
        return a.indexOf(v) !== -1;
    });
});

document.write('<pre>' + JSON.stringify(result,null,4) + '</pre>');

If anyone has a better solution and you want/can share it, thank you!

  • In my view Sopt avenges and avenges very well. If you want to discuss something related to this, I invite you to enter the chat Stack Burst. Anyway, I will be removing the comment from the answer because it has no relation to the problem discussed.

  • I thought the combination of filter with every, solved in a simple way a relatively complex problem. + 1 Could explain the logic?

  • 1

    With Arrow Function you are a little more optimized visually: https:/jsfiddle.net/bvnwzamu/

  • hahah, it’s true @Lucascosta, it’s the same thing, but written in a simpler way, so you can leave it in one line and it doesn’t get ugly. I have no habit of using Arrows in the - few - scripts I do. Thanks for the add-on. As for the explanation of logic I will comment below.

  • @Lucascosta answering his question about the logic used, the hardest part was to see that I could not use 3 distinct arrays to solve the problem - I could, but I would have to use many more lines of code - When I realized that it would be easier to use an array containing string arrays to solve everything, it was kind of natural for the rest of the solution. The shift function there at the beginning, reserves a "secret", when you give shift() in an array, the first element of that array will be removed, BUT, the function returns the removed element, which in this case, [...] (1/4)

  • [...]is the first array of the 3 arrays of the example, and since I only want the words that are in all arrays, it doesn’t matter which array I take (the ideal is to take whatever has the least elements, but abstract it here in the question). Continuing and knowing that whatever array I take, the filter() will be given over the array returned by shift() and the function filter() will be responsible for returning an array containing the elements that pass the test, that’s all it does, the function Every() I do not remember ever having used, it was a find to me, [...] (2/4)

  • [...]it iterates element by element by performing the check I want, which in case I basically check: this word (element) that is in this array, is also in this main array (the array returned by shift(), if it is, return it to filter() by the - little - that I understand, this is how the script behaves @Lucascosta, I am far from being a JS expert and much less in code optimization, but I liked this final solution, [...] (3/4)

  • [...]I believe that you can still optimize something, when I put a console.log() inside the script is strange, too many iterations in my view, but I could not optimize much more than that and reach the expected result. (4/4)

Show 3 more comments

2

A more "manual" version because you will have to iterate all the items of the first array.

Example

var objetos = ["abridor de garrafa", "abridor de latas", "adaga", "ábaco", "abajur", "abotoadura", "acetona", "açucareiro", "zabumba", "xícara", "zarabatana", "xilofone"];
var redondos = ["ábaco", "abajur", "abotoadura", "acetona", "açucareiro", "zabumba", "xícara"];
var cozinha = ["abridor de garrafa", "abridor de latas", "açucareiro", "xícara"];
var arma = ["adaga", "zarabatana"];
var musical = ["xilofone", "zabumba"];

function comuns(...arrays){

    let aux = 1,
        possui = false,
        npossui = false,
        novo = [];
        
    arrays[0].forEach(function(item){
       
       aux = 1;
       npossui = false;
       
       while (arrays[aux]){
          if (arrays[aux].indexOf(item) > -1) possui = true;
          else npossui = true;
          aux++;
       }
       
       if (possui && !npossui) novo.push(item);
    });
    
    return novo;
}

console.log(comuns(objetos,redondos,musical));

Browser other questions tagged

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