[javscript] reduce 함수에서 순서를 고려할 수 있나요?

조회수 671회
a = [2, 1, 3, 5, 3, 2] 
const countMap = a.reduce(function(accum,key,idx){
       accum[key] = accum[key] + 1 || 1; 
        return accum;
    },{});

console.log(countMap); // { '1': 1, '2': 2, '3': 2, '5': 1 }

countMap을 출력하면 accum 객체에 key 값이 들어간 순서대로 countMap에 저장이 되지 않고 key의 크기에 따라 출력이 되더라구요.

질문 1) 순서에 따라 저장할 수 있는 방법이 있을까요?

function firstDuplicate(a) {
    const answer = [];
    const countMap = a.reduce(function(accumkey,idx){
       accum[key] = accum[key] + 1 || 1; 
        answer.push([key,accum[key]]);
        // answer.push({ value:accum[key]});
        return accum;
    },{});

  console.log(answer);

저는 순서를 고려하기 위해 answer 배열을 만들고 각 경우마다 배열에 push를 해주어 순서를 고려하려고 하였는데요. 이때 answer.push({ key:accum[key]}); 와 같이 작성할 경우 key가 숫자값이 아니라 문자열 key 가 그대로 들어가더라구요. 그래서 .. 임시방편으로 answer.push([key,accum[key]]); 를 사용하였는데요.

질문2) 배열에 key를 문자그대로 key가 아닌 key 변수가 가리키는 값을 담으려면 어떻게 해야 하나요?

  • (•́ ✖ •̀)
    알 수 없는 사용자

3 답변

  • accum에 키-값이 "순서대로" 안 꼽히는 이유는 accum오브젝트이기 때문인 것으로 보입니다.

    var b = {9: 9, 3: 3};
    console.log(b);
    // { '3': 3, '9': 9 }
    // 띠용
    
    var c = [{9: 9}, {3: 3}];
    console.log(c);
    // [ { '9': 9 }, { '3': 3 } ]
    // 윽 이게 최선인가
    
    • 앗 ... 오브젝트는 자동적으로 순서대로 꼽히는군요.. 알 수 없는 사용자 2019.3.4 20:22
    • 생각해 보면 타당한 이치인 것이, 오브젝트는 하나의 값에 하나의 키가 이미 있고 오로지 그 키로만 그 값을 찾는단 말이죠. 그렇다면 그 값이 별도의 다른 키를 또 가져서 그걸로도 구분 가능해지면 곤란하거든요. 그리고 순서(인덱스)란 엄밀히 말하면 '키'니까요. 엽토군 2019.3.4 21:38
  • 아 .. 왜 맨날 질문하고나서 혹시 이렇게 해볼까? 하면 뭔가가 될까요... ㅜㅜ 일단 질문은 그대로 남아있습니다. reduce 함수에서 순서를 고려하는법이 있나요? 저는 잘 모르겠습니다.

    제가 원래 찾고자 하는것은 a라는 배열에서 같은원소가 2번 나오면 그 원소를 찾는것이었습니다. 그런데 reduce를 하면 가장 먼저 2번 나온 key를 리턴하지 않고 key의 순서대로 저장이 되더라구요.

    그런데 제가 질문을 하고나서 reduce 에서는 순서를 고려하기 어려우므로 for문을 통해 구현하면 어떨까? 라는 생각이 들어 위의 같은 역할을 하는 함수를 for문으로 작성해보았습니다.

    function firstDuplicate(a) {
        dic ={}
        for(let i = 0; i< a.length; i++){
            if(!dic[a[i]]) dic[a[i]] =1;
            else dic[a[i]] = dic[a[i]]+1;
    
            if(dic[a[i]] ===2) return a[i]
        }
        return -1
    

    그 결과 굳이 reduce 함수를 사용하지 않고 for문을 통해서 이렇게 쉽게 구현이 가능하다는것을 알게되었습니다.

    혹시 reduce 함수를 이용해서도 순서를 고려한 구현이 가능한지 알려주시면 감사할것같습니다. 아니라면 그냥 for문을 이용해야겠네요.

    • (•́ ✖ •̀)
      알 수 없는 사용자
  • 순서를 보장해야 한다면 Map을 사용하시길 권장드립니다.

    const countMap = a.reduce(function(accum,key,idx){
        accum.set(key, (accum.get(key) || 0) + 1); 
        return accum;
    }, new Map());
    

    이렇게 생성된 countMap

    for(let [key, value] of countMap) {
      console.log(key, value);
    }
    

    for...of... 로 insert한 순서대로 순차 접근이 가능합니다.

    • ES6를 사용하시는게 아니라면 그냥 자답내신대로 Array로 만드시는게... doodoji 2019.3.5 14:13
    • 아 아뇨.. 저 ES6 공부하고 있는데 아직 한참 부족해서요 ㅎㅎ 감사합니다!!! 알 수 없는 사용자 2019.3.5 15:28
    • 이게 제가 찾던 답이네요 ㅎㅎ... 알 수 없는 사용자 2019.3.5 15:29

답변을 하려면 로그인이 필요합니다.

프로그래머스 커뮤니티는 개발자들을 위한 Q&A 서비스입니다. 로그인해야 답변을 작성하실 수 있습니다.

(ಠ_ಠ)
(ಠ‿ಠ)