2017-01-28 2 views
2

자바 스크립트에 익숙하지 않아 약 한 달 동안 약 4 번이 질문을 시도했지만 아직 해결할 수 없습니다.Reduce를 사용하여 여러 개의 배열 비교하기

다음은 질문입니다. 입력 배열을 비교하고 모든 입력에있는 요소가있는 새로운 배열을 반환하는 함수 교차를 만듭니다. 보너스 : reduce!

형식은 다음과 같습니다

function intersection(arrays) { 
    // Your Code Goes Here 
} 

테스트 케이스 : 로그인해야 [15, 5]

console.log('Extensions 3 Test: ' + intersection([5, 10, 15, 20], [15, 88, 1, 5, 7]/*, [1, 10, 15, 5, 20]*/)); 

나의 현재 솔루션 : 비교하는 두 항목이 단지의 경우에 작동하지만,하지 세 번째의 경우, 루프를 통해 얻을 수있는 값을 다음 배열과 비교할 수 있도록 만들 수 있지만 올바른 경로에 있다고 생각하지는 않습니다 ... 또한 구현을 위해 reduce를 사용하지 않습니다. .. 그리고 나는 '논쟁'을 사용하기로되어 있는지 확실하지 않습니다. 어떤 도움을 주셔서 감사합니다! 정말 고맙습니다.

function intersection(arrays) { 
    array = []; 
    for (var i = 0; i < arguments.length; i++) 
    array.push(arguments[i]); 

    var result = []; 

    for(var i = 0; i < array.length - 1; i++) { 
    for(var j = 0; j < array[i].length; j++) { 
     if (array[i+1].includes(array[i][j])) 
     result.push(array[i][j]); 
    } 
    } 

    return result; 
} 
+0

왜 'lodash'(또는 '밑줄')을 사용하지 않습니까? 자바 스크립트에서 이러한 험한 경로를 위해 바퀴를 재발견하는 것은 미친 듯이 보입니다. – chriskelly

+0

@chriskelly : OTOH, 왜 그런 간단한 기능을 위해 그 중 하나를 드래그합니까? (그리고 나는 비슷한 라이브러리의 저자로서 저 자신을 말합니다.) –

+0

모든 응답 녀석 들께 감사드립니다! D –

답변

2

몇 가지 제안에 따르면 를 사용할 수 있습니다. 10, lodash 또는 내 개인 즐겨 찾기 Ramda (면책 조항 : 나는 저자 중 한 명입니다.)이 함수는 라이브러리를 고려하지 않을 정도로 간단해야합니다. 당신은 단지 참조/원시적 평등에 대한 걱정과 당신이 알고 싶은 곳의 경우를 고려할 필요가 없기 때문에이 적어도 너무 오래, 당신이 필요로하는 모든 것을

const intersection = (xs, ys) => xs.filter(x => ys.indexOf(x) > -1); 
intersection([5, 10, 15, 20, 3], [15, 88, 3, 1, 5, 7]); //=> [5, 15, 3] 

const intersectAll = (...xss) => xss.reduce(intersection); 
intersectAll([5, 10, 15, 20, 3], [15, 88, 3, 1, 5, 7], [1, 10, 15, 5, 20]); //=> [5, 15] 

내가 생각 : 다음은 간단한 버전입니다 {x: 1}{x: 1}은 같은 참조가 아니더라도 동일합니다. 필요하다면 Ramda의 intersection 기능을 살펴보십시오.또한

const intersection = (xs, ys) => xs.filter(x => ys.includes(x)); 

당신은 바이너리 기능이 필요가없는 경우, 당신은 단지 가변 인자를 만들 수 있습니다 : 경우 includes이 더 나은을 읽는 better supported, 내가 대신이 버전을 추천 할 것이라고

주 위의 두 가지를 결합하여 버전 :

const intersection = (...xss) => xss.reduce((xs, ys) => xs.filter(x => ys.indexOf(x) > -1)); 
1

직접 문제를 해결하지 않지만, 당신이 오픈 소스 라이브러리 underscore.js을 사용하여이 작업을 수행하려고하는 일을 할 수 있습니다.

_.intersection([1, 2, 3], [101, 2, 1, 10], [2, 1]); 
=> [1, 2] 

구현 된 방식에서 영감을 얻을 수 있습니다.

// Produce an array that contains every item shared between all the 
    // passed-in arrays. 
    _.intersection = function(array) { 
    if (array == null) return []; 
    var result = []; 
    var argsLength = arguments.length; 
    for (var i = 0, length = array.length; i < length; i++) { 
     var item = array[i]; 
     if (_.contains(result, item)) continue; 
     for (var j = 1; j < argsLength; j++) { 
     if (!_.contains(arguments[j], item)) break; 
     } 
     if (j === argsLength) result.push(item); 
    } 
    return result; 
    }; 
0

내가 당신을 위해 올바른 기능을 가지고 생각 : 위는 아래를 참조로 다른 underscore.js 기능에 의존 자신의 _.intersection 함수에 대한 함수 호출입니다. (참고 : 결과는 정렬되지 않습니다!)

var intersection = function() { 
    // merge deduped arrays from arguments 
    var arrays = Array.prototype.reduce.call(arguments, function(carry, array) { 
     return [].concat(carry, array.filter(function(item, index, origin) { 
      return origin.indexOf(item) === index; 
     })); 
    }, []); 

    var results = arrays.reduce(function(carry, item, index, arr) { 
     if(
      // just select items, which have more then 1 occurance 
      arr.filter(function(fItem) { 
       return fItem === item; 
      }).length > 1 && 
      // ... and which are not already in results 
      !~carry.indexOf(item) 
     ) { 
      carry = [].concat(carry,item); 
     } 
     return carry; 
    }, []); 

    return results; 
}; 
0

여기에 2 줄여 사용하는 버전입니다.

한 번만 배열 인스턴스 수를 추적 할 해시 맵 객체를 생성하는 첫 번째 반복

는 값을 반환 할 두 번째는 여기서 약간의 미세 조정을 사용할 수 없습니다 인수

function intersection(){ 
 
    // convert arguments to array of arrays 
 
    var arrays = [].slice.call(arguments); 
 
    // create an object that tracks counts of instances and is type specific 
 
    // so numbers and strings would not be counted as same 
 
    var counts= arrays.reduce(function(a,c){ 
 
    // iterate sub array and count element instances 
 
    c.forEach(function(val){ 
 
     var propName = typeof val + '|' + val; 
 
     // if array value not previously encountered add a new property   
 
     a[propName] = a[propName] || {count:0, value: val};  
 
     // increment count for that property 
 
     a[propName].count++; 
 
    }); 
 
    return a; 
 
    },{}); 
 

 
    // iterate above object to return array of values where count matches total arrays length 
 
    return Object.keys(counts).reduce(function(resArr, propName){ 
 
    if(counts[propName].count === arrays.length){ 
 
     resArr.push(counts[propName].value); 
 
    } 
 
    return resArr; 
 
    },[]); 
 
    
 
} 
 

 

 

 
console.log(intersection([5, 10, 15, 20], [15, 88, 1, 5, 7], [1, 10, 15, 5, 20]))

의 경기 수를 계산 인수가 충분하고 배열이 모두 배열되어 있는지 확인하십시오.

+0

고마워! 내가 찾고있는 것 같아! 내가 소화 할 시간이 필요해.하지만 내가 아는 어휘를 사용하여 답을 해줘서 고마워. D! –

+0

은 루프 내부에 몇 가지 콘솔 로깅 문을 추가 할 것을 제안했다. 무엇이 무엇인지에 대해 더 잘 느끼고,'console.log (counts)'를 검사해라. – charlietfl

0

여기는 바닐라 자바 ​​스크립트와 하나의 호출을 사용하여 내놓았습니다.

function intersection(){ 
var arrays = [].slice.call(arguments); 
var first = arrays[0]; 
var rest = arrays.slice(1); 

return first.reduce(function(all, item, index){ 
    var push = rest.every(function(subArray){ 
     return subArray.indexOf(item) > -1; 
    }); 
    if(push){ 
    all.push(item); 
    } 
    return all; 
},[]) 

} 

console.log(intersection([5, 10, 15, 20], [15, 88, 1, 5, 7], [1, 10, 15, 5, 20])); 
1

여기는 reduce를 사용하는 솔루션으로 빈 배열이 초기 값으로 교차로 전달됩니다.

숫자를 반복하고 각각이 하위 배열 중 하나에 나타나는지 확인하십시오.

그렇지 않으면 부울 isPresentInAll을 false로 설정하십시오.

3 가지로 모두 나타나고 교차 배열에 아직 나타나지 않은 경우 교차 배열로 푸시합니다.

function intersection(arrayOfArrays) { 
    return arrayOfArrays.reduce(function(intersection, subArray) { 
    subArray.forEach(function(number) { 
     var isPresentInAll = true; 
     for (var i = 0; i < arrayOfArrays.length; i++) { 
     if (arrayOfArrays[i].indexOf(number) === -1) { 
      isPresentInAll = false; 
     } 
     } 
     if (isPresentInAll === true && intersection.indexOf(number) === -1) { 
     intersection.push(number); 
     } 
    }); 
    return intersection; 
    }, []); 
} 
관련 문제