将基于 js 的下划线函数转换为 PlainJs 或 jquery

conversion of underscore js based function to PlainJs or jquery

问题: 我想获取对象数组的 inetrsection。

var a = [{id: 1, name: 'jake'}];
var b = [{id: 1, name: 'jake'}, {id: 4,name: 'jenny'}];
var c = [{id: 1,name: 'jake'}, {id: 4,name: 'jenny'}, {id: 9,name: 'nick'}];
intersect (a,b,c);// Find Intersection based on id key
// answer would be [{id: 1, name: 'jake'}]

我在这里找到了这个非常有帮助的答案 How to use underscore's "intersection" on objects?

但是 此解决方案使用 underscore.js 而我使用 jquery.

我似乎不知道 _.any 在做什么。 任何帮助将不胜感激。

这是完整的代码

代码: http://jsfiddle.net/luisperezphd/43vksdn6/

function intersectionObjects2(a, b, areEqualFunction) {
    var results = [];

    for(var i = 0; i < a.length; i++) {
        var aElement = a[i];
        var existsInB = _.any(b, function(bElement) { return areEqualFunction(bElement, aElement); });

        if(existsInB) {
            results.push(aElement);
        }
    }

    return results;
}

function intersectionObjects() {
    var results = arguments[0];
    var lastArgument = arguments[arguments.length - 1];
    var arrayCount = arguments.length;
    var areEqualFunction = _.isEqual;

    if(typeof lastArgument === "function") {
        areEqualFunction = lastArgument;
        arrayCount--;
    }

    for(var i = 1; i < arrayCount ; i++) {
        var array = arguments[i];
        results = intersectionObjects2(results, array, areEqualFunction);
        if(results.length === 0) break;
    }

    return results;
}
var a = [ { id: 1, name: 'jake' }, { id: 4, name: 'jenny'} ];
var b = [ { id: 1, name: 'jake' }, { id: 9, name: 'nick'} ];
var c = [ { id: 1, name: 'jake' }, { id: 4, name: 'jenny'}, { id: 9, name: 'nick'} ];

var result = intersectionObjects(a, b, c, function(item1, item2) {
    return item1.id === item2.id;
});

此解决方案计算具有相同 属性 和 returns 的相同给定对象,如果它们在两个数组 intersection().

function intersection(a, b, key) {
    function count(a) {
        o[a[key]] = o[a[key]] || { value: a, count: 0 };
        o[a[key]].count++;
    }
    var o = {}, r = [];
    a.forEach(count);
    b.forEach(count);
    Object.keys(o).forEach(function (k) {
        o[k].count === 2 && r.push(o[k].value);
    });
    return r;
}

function intersect(a, b, c, key) {
    return intersection(intersection(a, b, key), c, key);
}

var a = [{ id: 1, name: 'jake' }],
    b = [{ id: 1, name: 'jake' }, { id: 4, name: 'jenny' }],
    c = [{ id: 1, name: 'jake' }, { id: 4, name: 'jenny' }, { id: 9, name: 'nick' }],
    result = intersect(a, b, c, 'id');

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

现在可以使用这种样式的回调。

function (v) { 
    return v.id;
}

它需要 returns 一个可字符串化的值,并且可以包含其他值和组合,例如与姓名和年龄相交的示例(如果数据中存在):

function (v) { 
    return v.name + '|' + v.age;
}

function intersection(a, b, cb) {
    function count(a) {
        o[cb(a)] = o[cb(a)] || { value: a, count: 0 };
        o[cb(a)].count++;
    }
    var o = {}, r = [];
    a.forEach(count);
    b.forEach(count);
    Object.keys(o).forEach(function (k) {
        o[k].count === 2 && r.push(o[k].value);
    });
    return r;
}

function intersect(a, b, c, key) {
    return intersection(intersection(a, b, key), c, key);
}

var a = [{ id: 1, name: 'jake' }],
    b = [{ id: 1, name: 'jake' }, { id: 4, name: 'jenny' }],
    c = [{ id: 1, name: 'jake' }, { id: 4, name: 'jenny' }, { id: 9, name: 'nick' }],
    result = intersect(a, b, c, function (_) { return _.id; });

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

这是我的回答: 好处是

  1. 它让我可以自由地交叉任意多的对象

  2. 我可以使用比较函数,其中我可以使用等式或我想要的任何逻辑

代码:

var a = [ { id: 1, name: 'jake' } , { id: 4, name: 'jenny'}, { id: 9, name: 'nick'} ];
var b = [ { id: 1, name: 'jake' }, { id: 9, name: 'nick'} ];
var c = [ { id: 1, name: 'jake' }, { id: 4, name: 'jenny'}, { id: 9, name: 'nick'} ];


var intersectionObjects = function() {
  var results = arguments[0];
  var lastArgument = arguments[arguments.length - 1];
  var arrayCount = arguments.length;
  var areEqualFunction;
  //Internal function
  var _intersection_of_2_Objects = function(array1, array2, areEqualFunction) {
    var result = []
    $.each(array1, function(indexArray1, valueArray1) {
      $.each(array2, function(indexArray2, valueArray2) {
        if (areEqualFunction(valueArray1, valueArray2)) {
          result.push(valueArray2)
        }
      });
    });
    return result;
  };
  //
  if (typeof lastArgument === "function") {
    areEqualFunction = lastArgument;
    arrayCount--;
  }
  for (var i = 1; i < arrayCount; i++) {
    var array = arguments[i];
    results = _intersection_of_2_Objects(results, array, areEqualFunction);
    if (results.length === 0) {
      break;
    }
  }
  return results;
};

这样称呼它:

var _intersect = intersectionObjects(b, c, a, function(valueArray1, valueArray2) {
  return (valueArray1.name == valueArray2.name);
});
console.log(_intersect);