Javascript의 배열(Array)의 정렬(Sort)

사람이 처리할 수 있는 데이터의 양에는 한계가 있고, 컴퓨터는 이러한 한계를 가진 인간을 보조해주고 인간이 쉽고 빠르게 정보를 파악해 주는 기능을 제공합니다. 검색 결과 등과 같은 정보를 정렬하지 않고 사용자에게 제공할 경우 사용자는 자신이 찾고자 하는 데이터를 찾아 헤매게 됩니다. 하지만 정렬된 데이터라면 빠르게 데이터를 찾을 수 있습니다.

검색 결과를 담기에 적당한 자료 구조는 배열입니다. 특히 Javascript에서는요. 이러한 배열을 정렬하는 코드를 정리해 둡니다.

var numbers = [4, 2, 5, 1, 3];
numbers.sort(function(a, b) {
    return a - b;
});

위의 코드는 배열에 담긴 요소들을 정렬한 결과로 원래의 배열을 변경합니다.

아래는 배열에 담긴 데이터가 Key-Value를 가지는 Object 항목으로 구성된 경우에 대한 정렬 예입니다.

var items = [
    { name: 'Edward', value: 21 },
    { name: 'Sharpe', value: 37 },
    { name: 'And', value: 45 },
    { name: 'The', value: -12 },
    { name: 'Magnetic' },
    { name: 'Zeros', value: 37 }
];

items.sort(function(a, b) {
    var nameA = a.name;
    var nameB = b.name;

    if (nameA < nameB) {
        return -1;
    }

    if (nameA > nameB) {
        return 1;
    }

    return 0;
});

정렬 못지 않게 중요한 것이 필터링(Filtering)입니다. 검색 결과 중 내가 보고자 하는 데이터만을 보고, 아닌 것은 보여주지 않는 것이죠. 정렬과 필터링 기능은 기본적인 기능이지만, 제법 많은 프로그램에서 놓치고 있는 기능이기도 합니다.

웹에서의 레이아웃을 위한 구세주, Flex

웹의 CSS를 이용해 가로에 대한 가운데 정렬은 그럭저럭 쉽게 지정할 수 있지만, 세로 정렬은 왠지 트릭같은 방식으로 지정하는 느낌을 받는다. 그렇다보니, 세로 정렬이 필요한 레이아웃을 구성할때마다 고충이 생기는데.. 이럴때 flex라는 비교적 최신의 CSS 방식을 활용해 이러한 고충을 제거하고자 이 글을 정리한다. 사실 flex 방식은 그 내용이 제법 방대하다. 하지만 체계적인지라 여러번 살펴보면 충분이 이해하고 실제 업무에 활용할 수 있다.

일단 앞서 언급한 가로와 세로에 대한 가운데 정렬을 위한 flex 방식을 이 글을 통해 간단이 언급해 둔다. 가운데 정렬이 필요할때마다 flex를 사용하다보면.. flex의 그밖의 요소들이 하나씩 접근하게 될 것이기 때문이다. 기술이란 그 필요에 의해 사용되고, 자연스럽게 사용되어질때 사용자가 보다 쉽게 이해할 수 있기 때문이다.

아래의 dom 구성에 대한 코드가 있다.

DIP2K
김형준

.container 안에 .item 항목을 가로와 세로로 가운데 정렬하고자 한다면 아래와 같은 스타일을 지정하면 된다.


실제 결과는 아래와 화면처럼 가로와 세로에 대해 가운데로 정렬된 것을 볼 수 있다.

[xyz-ihs snippet=”flex-layout-center-align”]

DIV 요소는 display가 block이다. 그러나 flex의 내부의 항목으로 들어가게 되면 inline-block으로 변경된다는 점을 알 수 있다. 끝으로 이 글을 작성하기 위해 읽었던 문서는 “flexbox의 기본 개념”이다.

비트(Bit) 단위로 생각하기 (비트 연산)

거의 대부분의 프로그래밍 언어를 학습하다보면 나오는 비트 연산은 이진 파일 포맷 분석, 해시, 암호화 등이 아닐 경우 거의 사용되지 않는다. 그래서인지, 관련 내용을 그냥 눈으로만 보고 이해하거나, 그냥 넘기는 경우가 다반사인데.. 그러다보니 비트연산에 대한 깊이 있는 이해가 수반될 일이 없어 더욱더 비트 연산을 쓸일이 없게 된다.

사실 비트 연산은 매우 최적화된 연산이고, 모든 기능들.. 즉 그 모든 복잡한 기능들을 구성하는 가장 최소 단위라고 할 수 있다. 일단 최적화된 연산이라는 관점에서 그 활용처를 생각해보면, 상태값을 담아두기 위해 저장소로 활용될 수 있는데.. 만약 8개의 상태가 필요할 경우 총 8개의 boolean 타입이 필요하다. 언어에 따라 다르지만 boolean 타입의 변수를 위해 할당하는 메모리의 양은 비트연산을 통해 동일한 기능을 수행하는 것에 비해 엄청난 양의 메모리를 사용하며 그 속도 또한 엄청나게 느리다.

여기서 8개의 상태값을 담아 두는 비트연산 기능을 코드로 들어, 필자 스스로를 위한 비트 연산의 이해를 다져 본다.

8개의 상태값을 담기 위해 부호가 없는 8비트의 정수 변수인 states를 정의하였다. 즉 8개의 상태 값을 저장하기 위해 단 1바이트만을 사용하고 있다. 코드는 이 states 변수의 2번째와 4번째 그리고 7번째를 On으로 하고 나머지는 Off로 상태로 설정하는 코드이다.

var states uint8 = 1 << 1 | 1 << 3 | 1 << 6

이제 이 상태 변수를 통해 4번째의 상태를 파악하기 위해 다음의 코드가 필요하다.

if states&(1<<3) != 0 {
    fmt.Println("index 4 is ON")
}

그리고 상태에서 4번째만을 ON으로 하는 코드는 아래와 같다.

states = states | (1 << 3)

그리고 상태에서 4번째만을 OFF으로 하는 코드는 아래와 같다.

states = states &^ (1 << 3)

끝으로 4번째 상태를 토글(Toggle), 즉 ON이면 OFF로.. OFF면 ON으로 설정하는 코드는 아래와 같다.

states = states &^ (1 << 3)

웹 UI ㅡ Accordion

웹에서 제공하는 표준 UI는 상당히 투박해서 거의 사용하지 않고, jQuery UI 등과 같이 유명한 라이브러리를 사용해 웹 어플을 개발합니다. 그러나 필자는 기존의 웹 UI 라이브러리를 사용하지 않는데.. 이유는 내가 원하는 UI의 형태와 느낌을 표현하기 위해 상당이 많은 시간과 노력이 투자되어야 하거나, 불가능한 경우라고 포기하며 타협하게 되기 때문입니다.

이번에 웹에서 접고 펼치는 Accordion UI가 필요해서, 직접 만들어 사용하고 있는데요. 아래는 그 UI에 대한 샘플 결과 이미지입니다.

뭐, 그닥 이쁘다거나 세련된 모양은 아닙니다. 하지만 UI의 멋은 Content으로 완성된다고 믿는 저에겐 충분합니다. 아래는 위의 UI를 구성하기 위한 Javascript 코드입니다.

<div id="div"></div>

<script>
var ui = new XrUI.accordion("div",
    {
        width: "320px",
        height: "400px",
        top: "50px",
        left: "60px",
        title: "어코디언 UI"
    }
);

ui.addItem("item1");
ui.itemTitle("item1").innerHTML = "Title1";
ui.itemContent("item1").innerHTML = "Content1";

ui.addItem("item2")
ui.itemTitle("item2").innerHTML = "Title2";
ui.itemContent("item2").innerHTML = "Content2";

ui.addItem("item3")
ui.itemTitle("item3").innerHTML = "Title3";
ui.itemContent("item3").innerHTML = "Content3";
</script>

어코디언을 구성하는 항목의 제목과 내용을 직접 innerHTML 등으로 구성할 수 있도록 DOM 요소를 노출하고 있는데요. 이 부분이 향후 이 어코디언 UI를 내가 원하는 형태과 내용으로 자유롭게 구성할 수 있는 통로가 됩니다.

이렇게 만들어진 웹 UI는 컴포넌트로써 실제 프로젝트에서 아래와 같은 형태로 초기에 응용되어 활용되었습니다.

기본적이고 단순한 틀은 유지하면서, 최대한 컨텐츠를 활용하여 UI를 꾸미고 있습니다. 프로그램의 기능은 배포후 점진적으로 개선 발전되듯이 UI 역시 편의성 등의 개선을 이유로 변경됩니다. 결국 현재는 아래와 같은 형태로 활용되고 있습니다.

[Go] fogleman의 Go Graphics 라이브러리

Go는 그 목적이 시스템 및 서버 프로그래밍에 있음으로 그리기(Draw) API는 지원하지 않는다. 그러나 Go 언어에는 이러한 부족한 부분을 채워줄 매우 많은 그래픽 라이브러리 존재하는데, 그 중에 하나가 fogleman이 개발한 Go Graphic 라이브러(https://github.com/fogleman/gg)이다.

아래의 코드는 이 라이브러리를 이용해 필자가 작성한 테스트 코드이다. (사실 이글은 Go 마스터하기 라는 책을 다 보고, 다시 한번 더 볼 요량으로 파일을 정리하던 중에 코드를 이 블로그에 저장하기 위한 목적을 갖는다.)

package main

import "github.com/fogleman/gg"

func main() {
	const S = 256

	dc := gg.NewContext(S, S)

	dc.SetRGB(1, 1, 1)
	dc.Clear()

	if err := dc.LoadFontFace("font.ttf", 36); err != nil {
		panic(err)
	}

	dc.SetRGB(0, 0, 0)

	s := "한글ABC"
	n := 3 // "stroke" size

	for dy := -n; dy <= n; dy++ {
		for dx := -n; dx <= n; dx++ {
			if dx*dx+dy*dy >= n*n {
				// give it rounded corners
				continue
			}
			x := S/2 + float64(dx)
			y := S/2 + float64(dy)
			dc.DrawStringAnchored(s, x, y, 0.5, 0.5)
		}
	}
	dc.SetRGB(1, 1, 0)
	dc.DrawStringAnchored(s, S/2, S/2, 0.5, 0.5)

	dc.SavePNG("out.png")
}

결과는 아래와 같은 out.png 파일을 생성한다는 것이다. 파일로 생성하는 것은 필자의 목적에 맞기 때문인데, 이렇게 생성한 이미지를 네트워크를 타고 클라이언트에 전송되는 것이 목적이다. 또는 캐쉬 되거나…

위의 결과 외에도 이 라이브러리의 개발자가 언급한, 표현 가능한 결과물은 아래와 같으니 참고 바란다.

내용 정리 끝냈으니, 관련 소스 파일은 삭제 .. !