Сравните неуказанное количество массивов для общих значений в JavaScript

Я хотел бы знать, как сравнить два или более - потенциально неограниченных - массива для общих значений и эффективно вставить эти значения в новый массив. Ниже у меня есть функция, которая будет принимать неограниченное количество аргументов, но я не уверен, что это хорошее место для начала. Похоже, в PHP есть метод, который может делать то, что я хочу, называемый array_intersect. Javascript предлагает что-то подобное?

Примечание: я нашел примеры того, как это можно сделать с двумя или около того массивами, но я не нашел примеров того, как такие подходы могут применяться к неопределенному количеству массивов на данный момент. Поэтому я не считаю это дублирующим вопросом.

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

var sampleOne = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12];
var sampleTwo = [5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18];

function FindDirectRelation() {
    for(var i = 0; i < arguments.length; ++i) {
        console.log(arguments[i]);
        

    };
};

var directRelation = FindDirectRelation(sampleOne, sampleTwo);

Я все еще начинающий программист, поэтому, пожалуйста, убедитесь, что все объясняется так, чтобы мне было достаточно просто это понять.

3 ответа

Решение

Используя существующее пересечение, которое работает с 2 массивами, мы можем связать вместе общее подмножество, используя встроенный reduce() метод на массиве массивов, которые должны пересекаться:

function intersect(a, b) {
  var aa = {};
  a.forEach(function(v) { aa[v]=1; });
  return b.filter(function(v) { return v in aa; });
}

var r1=[1,2,3], 
r2=[1,3,4,5], 
r3=[5,1,3];

alert([r1, r2, r3].reduce(intersect)) // shows: 1,3

если вы определяете "пересечение" как просто находящийся в нескольких массивах (не в каждом), то это более сложно...

Убедитесь, что элементы первого массива также находятся в остальных массивах:

function multi_intersect(a) {
  var other_arrays = Array.prototype.slice.call(arguments, 1);

  return a . filter(function(elt) {
    return other_arrays.every(function(an) {
      return an.indexOf(elt) !== -1;
    });
  });
}

Попробуйте использовать Array.prototype.filter(), Array.prototype.indexOf()

var res = sampleOne.filter(function(val) {return sampleTwo.indexOf(val) !== -1})

var sampleOne = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12];
var sampleTwo = [5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18];
var arr = ["a", "b", "c"];
var arr1 = ["c", "d", "e"];
var arr2 = [2, 7];

function samples() {
  var args = Array.prototype.slice.call(arguments);
  var res = [];
  for (var i = 0, curr, next; i < args.length; i++) {
    if (args[i + 1]) {
      // set `curr` to array `i`
      curr = args[i];
      // set `next` to array `i + 1` if it exists
      next = args[i + 1]
    } else {
      // if at last index, set `curr` to `args` : input arrays 
      // flattened to single array , with element at `i` removed
      curr = [].concat.apply([], args.slice(0, args.length - 1));
      console.log(curr)
      // set next to current index
      next = args[i];
    };
    next = next.filter(function(val) {
      return curr.indexOf(val) !== -1 
             // filter duplicate entries at `res`
             && res.indexOf(val) === -1
    });
    res = res.concat.apply(res, next);
  };
  return res
}
var sample = samples(sampleOne, sampleTwo, arr, arr1, arr2);
console.log(sample); // [5, 6, 7, 8, 9, 10, 11, 12, "c", 2]

Другие вопросы по тегам