Javascript:设置数据结构:相交

时间:2015-08-10 23:40:47

标签: javascript set ecmascript-6

尝试让两个数据集相交但我无法做到:(例如,在我的代码中,相交mySet和mySet2应该产生“1”,因为它们的值都为“1”集。

var mySet = new Set();
var mySet2=new Set();
mySet.add(1);
mySet.add(2);
mySet.add("HELLOOOOO");
mySet2.add("hi");
mySet2.add(1);


var a = Array(mySet, mySet2);
console.log(a);

mySet.forEach(function(value) {
    console.log(value);
});


mySet2.forEach(function(value) {
    console.log(value);
});

function intersection_destructive(a, b)
{
    var result = new Array();
    while( mySet.length > 0 && mySet2.length > 0 )
    {
        if      (mySet[0] < mySet2[0] ){ mySet.shift(); }
        else if (mySet[0] > mySet2[0] ){ mySet2.shift(); }
        else /* they're equal */
        {
            result.push(mySet.shift());
            mySet2.shift();
        }
    }

    return result;
}

Set 1和Set 2都有“1”但我的函数(intersection_destructive)不返回它。我不确定如何与它们相交,我搜索了stackoverflow并找到了intersection_destructive,但它对我不起作用,我也试过了:

array1.filter(function(n) {
    return array2.indexOf(n) != -1
});

按照:Simplest code for array intersection in javascript

但是当我尝试运行它时,我在“过滤器”上收到错误。

6 个答案:

答案 0 :(得分:5)

要获得交集,您可以迭代集合中的项目并检查它们是否属于另一个项目:

var intersect = new Set();
for(var x of mySet1) if(mySet2.has(x)) intersect.add(x);

在ES7中,您可以使用array comprehensionsgenerator comprehensions来简化它:

var intersect = new Set((for (x of mySet1) if (mySet2.has(x)) x));

答案 1 :(得分:4)

可悲的是,你已经发现那里没有原生路口或工会的行动。虽然找到交叉路口并不是非常复杂:

<? 
  $user = Auth::user();
  if ($user)
    echo "<ul class="dropdown-menu">
            <li><a href="/myprofile">Profile</a></li>
            <li><a href="#">Another action</a></li>
            <li><a href="/auth/logout">Logout</a></li>
            <li role="separator" class="divider"></li>
            <li class="dropdown-header">Nav header</li>
            <li><a href="#">Separated link</a></li>
            <li><a href="#">One more separated link</a></li>
          </ul>";
  else
    echo <a href ="signin">SignIn</a>;
?>

答案 2 :(得分:2)

您一直在尝试阵列交叉方法。你不能在ES6套装上使用它们。相反,使用

function intersect(...sets) {
    if (!sets.length) return new Set();
    const i = sets.reduce((m, s, i) => s.size < sets[m].size ? i : m, 0);
    const [smallest] = sets.splice(i, 1);
    const res = new Set();
    for (let val of smallest)
        if (sets.every(s => s.has(val)))
             res.add(val);
    return res;
}

答案 3 :(得分:1)

来自example:intersection_destructive需要2个ARRAYS而不是2个SETS。以下是使用intersection_destructive示例的代码。

// These must be sorted arrays!
var mySet = [1,2,6];
var mySet2 = [1,2,5];

// Takes 2 Arrays
// array properties: shift
function intersection_destructive(a, b)
{
    var result = [];
    while( a.length > 0 && b.length > 0 )
    {
        if      (a[0] < b[0] ){ b.shift(); }
        else if (a[0] > b[0] ){ b.shift(); }
        else /* they're equal */
        {
            result.push(a.shift());
            b.shift();
        }
    }

    return result;
};

var result = intersection_destructive(mySet, mySet2);
console.log(result); // Output: [1,2]

答案 4 :(得分:1)

这将适用于集合和数组。它将返回set1的任何类型。参数可以是混合类型。

/**
 * Returns the intersection of ES6 Set objects. i.e., returns a new set with only elements contained in all the given sets.
 * 
 * @param {Set|Array} set1 First set
 * @param {Array<Array|Set>} sets Other sets
 * @returns {Set|Array} Intersection
 */
export function intersection(set1, ...sets) {
    if(!sets.length) {
        return set1;
    }
    const tmp = [...set1].filter(x => sets.every(y => Array.isArray(y) ? y.includes(x) : y.has(x)));
    return Array.isArray(set1) ? tmp : new Set(tmp);
}

我构建它用于处理Sets,但后来我意识到将数组转换为集合可能会更昂贵,因此我可以使用.has一次,而不是仅使用.includes。< / p>

答案 5 :(得分:0)

使用Array.filter()是一种有用的模式。您需要使用Array.from()将您的集转换为数组。还要确保将较小的一组过滤到较大的一组。 see fiddle

var mySet = new Set();
var mySet2=new Set();
mySet.add(1);
mySet.add(2);
mySet.add("HELLOOOOO");
mySet2.add("hi");
mySet2.add(1);

console.log(intersection_destructive(mySet, mySet2));

function intersection_destructive(a, b)
{

    // filter over the shorter set and convert sets to Array's so we have filter
    if (a.length > b.length) {
        var array1 = Array.from(a);
        var array2 = Array.from(b);
    } else {
        var array1 = Array.from(b);
        var array2 = Array.from(a);
    }

    var result = array1.filter(function(n) {
        return array2.indexOf(n) != -1
    });

    return result;
}