파이썬 zip 함수 - 자바스크립트 구현 (feat. 제너레이터)

skyepodium·2022년 4월 14일
0
post-custom-banner

그냥 제너레이터 사용하면 구현할 수 있다구

1. python zip

1) 개요

파이썬 내장 함수 zip이 있습니다.

for each로 두개의 리스트를 동시에 순회할 수 있습니다.

a = [1, 2, 3, 4, 5, 6, 7]
b = ['a', 'b', 'c', 'd', 'e']

for x, y in zip(a, b):
    print(x, y)
"""
1 a
2 b
3 c
4 d
5 e
"""

2) 의문

개인적으로는 알고리즘 풀때 자주 사용하고 있고

요즘 자바스크립트로도 알고리즘 푸는데, 자바스크립트에는 zip 함수가 없습니다.

그냥 제너레이터 보니 가능할것 같습니다. 구현해봅시다.

2. 자바스크립트 zip

제너레이터 사용했더니 금방되었다.

const a = [1, 2, 3, 4, 5]
const b = ['a', 'b', 'c', 'd', 'e']

function* zip(a, b) {
    const n = Math.min(a.length, b.length)

    for (let i = 0; i < n; i++) yield [a[i], b[i]]
}

for(const q of zip(a, b)) {
    console.log(q)
}

[...zip(a, b)].forEach(x => console.log(x))

/*
    [ 1, 'a' ]
    [ 2, 'b' ]
    [ 3, 'c' ]
    [ 4, 'd' ]
    [ 5, 'e' ]

 */

3. 실전 테스트

leetcode에 적용했고, 잘 돌아가는것 같습니다.

1) leetcode - create-target-array-in-the-given-order

const createTargetArray = (nums, index) => {
    // 1. zip
    function* zip(a, b) {
        const n = Math.min(a.length, b.length)

        for (let i = 0; i < n; i++) yield [a[i], b[i]];
    }

    // 2. init
    let res = [];

    // 3. loop
    [...zip(nums, index)].forEach(([num, idx]) => res = res.slice(0, idx).concat([num]).concat(res.slice(idx)))

    return res
};

2) leetcode - check-if-one-string-swap-can-make-strings-equal

forEach는 중간에 종료하는것이 불가능해서, for of를 사용했습니다.

const areAlmostEqual = (s1, s2) => {
    // 0. zip
    function* zip(a, b) {
        const n = Math.min(a.length, b.length)
        for(let i=0; i<n; i++) yield [a[i], b[i]]
    }

    // 1. init
    if(s1 === s2) return true

    const base = []
    let cnt = 0

    // 2. loop
    for(const [c1, c2] of zip(s1, s2)) {

        if(c1 !== c2) {
            cnt++
            base.push([c1, c2])
        }

        if(cnt >= 3) return false
    }

    return base.length === 2 && base[0][0] === base[1][1] && base[0][1] === base[1][0]
};

3) leetcode - merge-strings-alternately

const mergeAlternately = (word1, word2) => {
    function* zipLongest(a, b, fillValue) {
        const n = Math.max(a.length, b.length)

        for (let i = 0; i < n; i++) {
            const aVal = i < a.length ? a[i] : fillValue
            const bVal = i < b.length ? b[i] : fillValue
            yield [aVal, bVal]
        }
    }

    return [...zipLongest(word1, word2, "")]
        .map(([x, y]) => `${x}${y}`)
        .join("")
}
profile
callmeskye
post-custom-banner

0개의 댓글