2017-02-13 9 views
1

Этот вопрос задан так много раз, но я не могу сделать то, что хочу, поэтому прошу вас о помощи.Как сравнить два массива в JavaScript, даже если они не упорядочены?

У меня есть 2 массива checkMyDataSources и lesInfosMachines.

Мне нужно пройти checkMyDataSources, чтобы проверить, нет ли каких-либо предметов в lesInfosMachines.
Содержание checkMyDataSources может быть чем-то вроде ["datasource_A","datasource_B","datasource_D","datasource_C"], а имя связано с именем каждого элемента в lesInfosMachines, который содержит такую ​​вещь, как ["A","B","C","D"].

Проблема заключается в том, что я не в состоянии пройти через все checkMyDataSources, я имею в виду, когда клетка А и Amachine разные его называют createDataSource несмотря на Amachine, может быть в клетке D.

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") 
    } 

I надеюсь, что мой вопрос понятен и спасибо за помощь

[EDIT] это мой выход: enter image description here

[EDIT2] для упрощения я хочу проверить aMachine на A, B, C, D в checkMyDataSources и если не aMachine в одной из этих клеток (но в конце), то звоните createDataSource()

+1

Как насчет использования 'if { .indexOf ()> -1}'? – reporter

+0

@репортер, что он собирается делать? – Jerome

+1

Я считаю, что было бы лучше, если бы вы четко писали, что ваши входы и что вы ожидаете от своих выходов. –

ответ

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 
    

путем объединения функций, таких как filter, every и some, вы можете реализовать многие алгоритмы очень идиоматично, не полагаясь на трудно понятные и даже семантически бессмысленные, петли и индексы for.

+0

Жаль, это очень приятно! Я попытаюсь использовать этот метод для другого варианта использования – Jerome

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' ] 
+0

Нет, я ничего не слышал об этом, но это выглядит очень интересно. Я посмотрю на это, я уверен, что это может быть полезно для некоторых из моих вариантов использования. – Jerome

+1

Это не полезно, это важно :) – Gab

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, и если это так я разрешаю называть создать метод

1

Вместо подключения двух петель, что приводит к множественным comparsions одного и того же элемента, вы можете использовать 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") 
} 

В противном случае вам придется реорганизовать ваши циклы, как в ответе Джерамиса.

+0

Я Джером ^^, я постараюсь реализовать ваше решение, это звучит лучше, чем у меня. – Jerome