如何在JavaScript中比较两个数组,即使它们没有被排序?

时间:2017-02-13 13:18:42

标签: javascript arrays meteor

这个问题被问过很多次,但我无法做出我想要的东西,所以我请求你的帮助。

我有2个数组checkMyDataSourceslesInfosMachines

我需要浏览checkMyDataSources以检查lesInfosMachines中是否有任何项目发生。
checkMyDataSources的内容可以是["datasource_A","datasource_B","datasource_D","datasource_C"],其名称与lesInfosMachines中包含["A","B","C","D"]之类的内容的每个项目的名称相关联。

问题在于我无法通过所有checkMyDataSources,我的意思是当细胞A和Amachine不同时它会调用createDataSource,尽管Amachine可能在细胞D中。< / p>

var lesInfosMachines = InfosMachines.find({});
    if(checkMyDataSources.length < 1){
      console.log("there is not datasource, we will create them all");
      callInitDS();
    }else{
      console.log("there is datasource, we will check them");
      lesInfosMachines.forEach(Meteor.bindEnvironment(function(machineInfo) {
        console.log("test machine " + machineInfo.nameMachine)
        for (var i = 0; i < checkMyDataSources.length; i++) {
          console.log("test on " + checkMyDataSources[i].name.split("_")[1]);

          if(checkMyDataSources[i].name.split("_")[1] === machineInfo.nameMachine){
            console.log("Datasource:  " + machineInfo.nameMachine + " already exist." );
          }else{
            if(machineInfo.ipAddr != null){
              console.log("going to create " + machineInfo.nameMachine);
              createDataSource(machineInfo.nameMachine, machineInfo.ipAddr);
            }else{
              console.log("going to create " + machineInfo.nameMachine + 
                          " with a fake @ip because it was null 
                            ONLY FOR TESTING WE NEED TO REMOVE THIS"
                         );
              createDataSource(machineInfo.nameMachine, "myFakeIP");
            }
          };
        }
      }));
      console.log("test finished")
    }

我希望我的问题是可以理解的,谢谢你的帮助

[编辑]这是我的输出: enter image description here

[EDIT2]简化我想在checkMyDataSources的A,B,C,D上测试aMachine,如果其中一个单元格中没有aMachine(但最后),则调用{{1 }}

4 个答案:

答案 0 :(得分:2)

你听说过lodash吗?

const _ = require('lodash');

let checkMyDataSources = ["datasource_A","datasource_B","datasource_D","datasource_C"];
let lesInfosMachines = ["A","B","C"];
_.difference(checkMyDataSources, _.map(lesInfosMachines, (elt) => 'datasource_' + elt));

>[ 'datasource_D' ]

答案 1 :(得分:1)

您可以使用Array.prototype.includes()

而不是连接两个循环,导致同一元素的多次比较

这会使您的代码看起来像这样:

var lesInfosMachines = InfosMachines.find({});
if (checkMyDataSources.length < 1) {
    console.log("there is not datasource, we will create them all");
    callInitDS();
} else {
    console.log("there is datasource, we will check them");
    lesInfosMachines.forEach(Meteor.bindEnvironment(function(machineInfo) {
        console.log("test machine " + machineInfo.nameMachine);
        if (checkMyDataSources.includes("datasource_" + machineInfo.nameMachine) {
                console.log("Datasource:  " + machineInfo.nameMachine + " already exist.");
            } else {
                if (machineInfo.ipAddr != null) {
                    console.log("going to create " + machineInfo.nameMachine);
                    createDataSource(machineInfo.nameMachine, machineInfo.ipAddr);
                } else {
                    console.log("going to create " + machineInfo.nameMachine + " with a fake @ip because it was null ONLY FOR TESTING WE NEED TO REMOVE THIS");
                    createDataSource(machineInfo.nameMachine, "myFakeIP");
                }
            };
        }
    }));
    console.log("test finished")
}

否则你将不得不重新组织你的循环,就像杰罗姆回答一样。

答案 2 :(得分:1)

const datasources = ["datasource_A", "datasource_B", "datasource_D", "datasource_C"];
const lesInfosMachines = ["A", "D", "C"];
const prefixLength = "datasource_".length
  • 如果您想在datasources上获取lesInfosMachines

    datasources.filter((d) => lesInfosMachines.every((l) => l !== d.slice(prefixLength)))
    ["datasource_B"]
    
  • 如果您希望在datasources上获得 lesInfosMachines

    datasources.filter((d) => lesInfosMachines.some((l) => l === d.slice(prefixLength)))
    ["datasource_A", "datasource_D", "datasource_C"]
    
  • 如果 true中的某些datasources以及lesInfosMachines,则希望它返回false

    let otherLesInfosMachines = ["X", "Y", "Z"]
    
    datasources.some((d) => otherLesInfosMachines.some((l) => l === d.slice(prefixLength)))
    false
    
    datasources.some((d) => lesInfosMachines.some((l) => l === d.slice(prefixLength)))
    true
    

通过组合filtereverysome等功能,您可以非常惯用地实现许多算法,而不必依赖难以理解,甚至语义无意义,{{ 1}}循环和索引。

答案 3 :(得分:0)

我使用boolean这样找到了解决方案:

var hasTestedAll = false;
var lesInfosMachines = InfosMachines.find({});
    if(checkMyDataSources.length < 1){
      console.log("there is not datasource, we will create them all");
      callInitDS();
    }else{
      console.log("there is datasource, we will check them");
      lesInfosMachines.forEach(Meteor.bindEnvironment(function(machineInfo) {
        console.log("test machine " + machineInfo.nameMachine)
        for (var i = 0; i < checkMyDataSources.length; i++) {
          console.log("test on " + checkMyDataSources[i].name.split("_")[1]);

              if(checkMyDataSources[i].name.split("_")[1] === machineInfo.nameMachine){
                if(i == checkMyDataSources.length-1){
                  hasTestedAll = true;
                }
                console.log("Datasource:  " + machineInfo.nameMachine + " already exist." );
              }else if(hasTestedAll){
                if(machineInfo.ipAddr != null){
                  console.log("going to create " + machineInfo.nameMachine);
                  createDataSource(machineInfo.nameMachine, machineInfo.ipAddr);
                }else{
                  console.log("going to create " + machineInfo.nameMachine + " with a fake @ip because it was null ONLY FOR TESTING WE NEED TO REMOVE THIS");
                  createDataSource(machineInfo.nameMachine, "myFakeIP");
                }
              };
        }
      }));
      console.log("test finished")
    }

(抱歉CodeSnipet无法正常工作,但我无法使用正确的对齐方式粘贴代码)

所以它测试我是否在checkMyDataSources的最后一个单元格中,如果是这种情况我允许调用create方法