자신 만의 'misc utils'라이브러리가 있습니까? 가장 자랑스러운 부분은 무엇입니까? [닫은]


32

나는 우리 중 많은 사람들이 자주 사용하는 도구와 유틸리티를 사용하여 작은 개인 라이브러리를 유지한다는 것을 알고 있습니다.

나는 16 살 때부터 광산을 가지고 있었기 때문에 상당히 큰 규모로 자랐습니다. 내가 쓴 것들 중 일부는 이후 프레임 워크에 추가되었습니다. 나는 LINQ 이전의 유전자 알고리즘과 함께 사용하기 위해 표현 트리를 구현 한 적이 거의 없었습니다. 그러나 최근에 나는 그것을 겪고 .NET 4.0으로 업그레이드하고 관심을 다시 불러 일으켰습니다.

그래서 나는 당신이 당신의 라이브러리를 무엇에 사용하는지 궁금합니다. 유용한 작은 스 니펫을위한 멋진 아이디어를 얻을 수있을 것입니다.

그래서 내 질문은 :

  • 기타 유틸리티 라이브러리가 있습니까?
  • 어느 부분이 가장 자랑스럽고 왜 그런가요?

원하는 경우 코드 예제를 제공하십시오. :-)


아무도 대답을 찬성하지 않는 것 같습니다 ...
Joey Adams

@Joey Adams 맞아? 현재 17 개의 질문 표와 6 개의 답변 표가 있습니다.
Nicole

나는 업 보팅 할 가치가있는 답변을 실제로보고 있지 않습니다. 공감대 란 무엇을 의미합니까? 질문의 본질은 대답이 단지 "오. 멋지다"는 것입니다. 어떤 반응을 보이면 모든 것을지지하거나 전혀하지 않습니다. (그리고 나는 모든 대답을 찬성하는 것을 좋아하지 않아 단지 거기에 오게한다. 다른 것이 없다면, 나는 투표에서 벗어났다. : P)
Adam Lear

@Anna Lear, 알았어요, 당신은 변명입니다 :)
Nicole

3
괜찮은 유틸리티는 github에 올려 놓고 세계와 공유해야합니다. 진정으로 좋으면 숨겨 두는 것이 합리적이지 않습니다.
Job

답변:


27

아니.

나는 12 명의 개발자들이 모두 자신 만의 작은 "util.h"스타일 라이브러리를 프로젝트에 추가하고, 일관되지 않은 함수 이름과 동작의 거대한 혼란으로 바뀌는 악몽 같은 효과를 보았습니다. PHP와 매우 흡사합니다. 그래서 나는 그런 일을 피합니다.

C # 및 python과 같이 가능할 때마다 필요한 모든 도구와 라이브러리를 제공하는 프로그래밍 환경을 사용하여 그렇게 할 필요가 없습니다.


7
나는 조직적인 목적으로 도서관을 꾸준히 재 작성합니다.
Maxpm

3
utils 패키지가 악몽으로 변했다고해서 모든 것이 나쁜 것은 아닙니다. 어떻게 피할 수 있고 더 많은 코드 복제가 없는지 알 수 없습니다. 따라서 테스트 성능이 저하되고 효율성이 떨어집니다.
Nicole

2
@Renesis : utils 패키지는 goto 문만큼이나 비참합니다. 물론 그 자체로는 그다지 나쁜 것은 아니지만 조만간 항상 재앙이되는 것처럼 보입니다. 코드 복제와 관련하여 거의 모든 프로젝트에서 비슷한 작업을 수행하고 파이썬이나 C #과 같은 작업을 수행하는 경우 다른 사람들도 그 작업을 수행했을 것이고 아마도 표준 라이브러리에있을 것입니다.
whatsisname

6
필자의 경험에 따르면, 자체 라이브러리를 보유한 엔지니어는 시스템이 제공하는 라이브러리보다 먼저 라이브러리를 사용하는 것이 좋으므로 개인 라이브러리를 사용하는 것은 좋지 않습니다. 예전에 절대적으로 자신의 '나 strlen'기능이라고 확신했다 사람이 있었다 빠르게 , 컴파일러가 제공하는 것보다 그가 쓴 있기를 . 다른 사람들이 더 잘할 수 있음을 인정하기 위해 strlen이 몇 가지 인라인 어셈블리 지침을 보여주는 간단한 데모가 필요했습니다.
JBR 윌킨슨

4
@JBRWilkinson 요점을 잘 알고 있습니다. 모든 프로그래머가 공통 코드를 개발하는 데 적합한 것은 아닙니다.
Nicole

15

SmartFormat

내가 가장 좋아하는 유틸리티는 내가 작성한 것입니다. 간단한 문자열 작성기 / 포매터로 정확한 문법으로 데이터를 문자열로 쉽게 변환 할 수 있습니다.

예를 들어, 대부분의 프로그래머는 템플릿에서 텍스트를 작성 "There are {0} items remaining" 하지만 문법 오류가 발생합니다 "There are 1 items remaining".

따라서 SmartFormat을 사용하면 다음을 작성할 수 있습니다 "There {0:is|are} {0} item{0:|s} remaining"..

당신은 대체 String.Format(...)와 함께 Smart.Format(...)하고 바로 그거야!

SmartFormat의 코드는 오픈 소스 : http://github.com/scottrippey/SmartFormat/wiki


이것은에서 사용하는 형식을 상기시킵니다 java.text.MessageFormat.
barjak

@barjak 재미있는! "조건부"형식을 연구하는 데 오랜 시간을 보냈으며 지금까지 비슷한 것을 찾지 못했습니다! MessageFormatChoiceFormat놀라 울 정도로 유사한 구문을 허용 클래스를! 설명서의 예 : "There {0,choice,0#are no files|1#is one file|1<are {0,number,integer} files}.". 이 언급을 언급 해 주셔서 감사합니다.
Scott Rippey 2019

@barjak SmartFormat 에는 더 많은 기능이 있습니다. 조건부 서식은 bool, 날짜, 시간 범위 및 개체와 같은 모든 데이터 형식에 적용됩니다. 또한와 같은 고급 연산자를 지원합니다 "{Count:<0?negative|=5?five|>50&<100?large|other}". 그것은 반영을 가지고있다 (즉 "There are {items.Length} items", 배열 아이템들과
타임스 팬

실제로 강력 해 보입니다. 배열 형식이 서로 맞물려 있습니다.
barjak

@ barjak : 예, 배열 형식이 정말 유용합니다! 이 예를 확인하십시오 : Smart.Format("There are {0.Count} files: {0:'{}'|, |, and }.", files);결과 "There are 3 files: 'a.txt', 'b.txt', and 'c.txt'.". 그것 없이는 "현지화"를 상상할 수 없습니다.
Scott Rippey

7

K 조합기 (C #, Scala)

루비에서 K 콤비 네이터를 자주 사용합니다.이 예제와 같이 폴딩 작업이 반환 값이 아닌 부작용을 통해 수행 될 때 주로 폴드로 사용됩니다.

some_collection.reduce(Hash.new(0)) {|acc, el| acc[el] += 1 }

각 요소가에서 얼마나 자주 발생하는지 계산합니다 some_collection. 불행히도, 블록은 각 반복마다 누산기의 새로운 값을 반환해야하기 때문에 실제로 작동하지 않지만 Ruby 할당에서는 할당 된 값으로 평가됩니다.

따라서 다음과 같이 누산기의 새 값을 명시 적으로 반환해야합니다.

some_collection.reduce(Hash.new(0)) {|acc, el| acc[el] += 1; acc }

그러나 접는 기능을 사용하는 기능적 스타일에서 이러한 명시 적 시퀀싱을 발견했습니다. K 컴비 네이터 ( Object#tap루비에서 호출 됨) :

some_collection.reduce(Hash.new(0)) {|acc, el| acc.tap { acc[el] += 1 }}

나는 C # (대부분 어떤 이유로 인해 List.Addreturn void대신에 return 과 같은 콜렉션 뮤 테이터 때문에 this)과 Scala에서 이미 두 번 놓쳤습니다 .

namespace GenericExtensions
{
    public static class GenericExtensions
    {
        public static T Tap<T>(this T o, Action<T> f)
        {
            Contract.Requires(o != null);
            Contract.Requires(f != null);

            f(o);
            return o;
        }

        public static T Tap<T>(this T o, Action f)
        {
            Contract.Requires(o != null);
            Contract.Requires(f != null);

            f();
            return o;
        }
    }
}

스칼라에서 :

class Tap[T](o: T) {
  def tap(f: T => Unit) = { f(o); o }
  def tap(f: => Unit) = { f; o }
}

object Implicits { implicit def any2Tap[T](o: T) = new Tap(o) }

신원 기능 (루비)

루비에서 누락 된 것은 아이디 기능에 액세스하는 좋은 방법입니다. Haskell은 이름 id아래에 Scala 라는 이름으로 식별 기능을 제공합니다 identity. 이를 통해 다음과 같은 코드를 작성할 수 있습니다.

someCollection.groupBy(identity)

루비에서 동등한 것은

some_collection.group_by {|x| x }

혀를 정확히 굴리지 않습니까?

수정은

IDENTITY = -> x { x }

some_collection.group_by(&IDENTITY)

ForEach (.NET)

C #에서 또 다른 누락 된 방법 :

namespace IEnumerableExtensions
{
    public static class IEnumerableExtensions
    {
        public static void ForEach<T>(this IEnumerable<T> xs, Action<T> f)
        {
            Contract.Requires(xs != null);
            Contract.Requires(f != null);

           foreach (var x in xs) f(x);
        }
    }
}

3
마지막 예제는 계산 된 디자인 결정이라고 생각합니다. 의 개념은 ActionLINQ의 설계 원칙에 위배 부작용을 의미한다.
ChaosPandion

1
@ChaosPandion : 이것이 LINQ와 어떤 관련이 있습니까?
Jörg W Mittag

@ Jörg W Mittag- IEnumerableLINQ 용 확장 기능이 추가되었습니다.
ChaosPandion

2
@ ChaosPandion : 나는 여전히 이해하지 못한다. ForEachLINQ 연산자가 아닙니다. LINQ 연산자에만 적용되는 제한이 LINQ 연산자 ForEach가 아닌에 적용되어야하는 이유는 무엇 입니까? 그리고 왜 부작용이 금지 IEnumerable.ForEach되었지만 허용 List.ForEach됩니까? 또한, 왜 부작용에 대한 금지되어 IEnumerable.ForEach있지만, 허용 foreach?
Jörg W Mittag

@ Jörg W Mittag-내가 말하는 것은 확장에서 누락되었다는 사실은 디자인 결정이었습니다. 사실 List<T>A가 들어는 ForEach이 변경 가능한 유형 점을 고려 합리적이다.
ChaosPandion

6

Java 유형 변환기가 있습니다. 공개 서명이 있습니다

public static <T> T convert(Object sourceValue, Class<T> destinationType)

소스 값을 대상 유형으로 변환하는 것이 가장 좋습니다. 기본적으로 정적으로 입력 된 언어 내에서 동적 입력을 할 수 있습니다 :-)

실제로 박스형 숫자 유형에 유용합니다. 예상 한 Integer위치에 놓을 수 없다는 것이 얼마나 짜증나 Long는가? 문제 없습니다, 그냥 변환하십시오. 또는 함수가을 기대 double하지만 null거기에 넣어야한다면 어떨까요? NPE 인 카붐 하지만 그것을 통해 convert, 당신은 얻을 NaN.


재미있는 해결책. Long은 항상 정수를 확장해야한다고 생각했습니다. 그러나 그럼에도 불구하고 여전히 오토 박스 문제가있을 것입니다 (오토 박스가 상속에 작동 할 방법이 없다는 것을 아는 한). 또한 NaN지원 을 위해 +1 .
Nicole

NaN우수합니다. 정수에는 그런 것이 없다는 것이 너무 나쁩니다. 나는 Integer.MIN_VALUE컨벤션으로 사용 했습니다. 그것은 자동 (유엔) 권투는 취급하지 않는 이유를 모르겠어요 기본값 인 0과 달리, 일반적으로 "이상한 충분가"발견 할 수 있어요 (Double) null으로 NaN. IMHO의 확실한 솔루션입니다.
투입 Joonas Pulakka

6

내가 작성한 기타 코드 중 대부분은 CCAN에 있으며 나머지는 기존 오픈 소스 프로젝트에서 더 나은 버전을 찾는 경향이 있습니다. 요즘에는 응용 프로그램 별 변형을 작성하거나 스스로 릴리스 할 수있는 범용 모듈을 작성하기 위해 점점 덜 범용적인 "misc"코드를 작성하고 있습니다.

기음

여기에 함수와 typedef가 두 번 이상 사용되었습니다. 타이밍이 필요한 애플리케이션의 경우 단순성 측면에서 밀리 초를이기는 것은 어렵습니다.

#include <stdint.h>
#include <sys/time.h>

typedef int64_t msec_t;

static msec_t time_ms(void)
{
    struct timeval tv;
    gettimeofday(&tv, NULL);
    return (msec_t)tv.tv_sec * 1000 + tv.tv_usec / 1000;
}

그리고 반복해서 사용하는 경향이있는 더 많은 C 함수 :

/* Remove a trailing newline, if present. */
void chomp(char *buffer)
{
    if (!*buffer)
        return;

    while (*buffer)
        buffer++;

    if (buffer[-1] == '\n')
        buffer[-1] = 0;
}

/*
 * Skip whitespace, update the pointer, and return it.
 * Example:
 *
 * switch (*skipSpace(&s)) {
 *     case '\0':
 *         ...
 *     case '(':
 *         ...
 */
const char *skipSpace(const char **sptr)
{
    const char *s = *sptr;
    while (isspace(*s))
        s++;
    *sptr = s;
    return s;
}

/* Scramble an array of items uniformly. */
void scramble(void *base, size_t nmemb, size_t size)
{
    char *i = base;
    char *o;
    size_t sd;
    for (;nmemb>1;nmemb--) {
        o = i + size*(rand()%nmemb);
        for (sd=size;sd--;) {
            char tmp = *o;
            *o++ = *i;
            *i++ = tmp;
        }
    }
}

하스켈

Haskell의 nub :: (Eq a) => [a] -> [a]함수는 타입 시그니처에 의해 두 요소가 같은지 테스트 만 가능하기 때문에 O (n²)입니다. 간단한 O (n log n) 대안은 map head . group . sort출력을 생성하기 전에 전체 입력 목록을 강제 실행해야하지만 nub출력을 즉시 시작할 수 있습니다. 다음은 A에서 nub이미 본 항목을 수집 하는 O (n log n) 대안 입니다 Data.Set.

module Nub (nub') where

import Prelude
import Data.Set (empty, member, insert)

nub' :: Ord a => [a] -> [a]
nub' xs = loop xs empty where
    loop [] _ = []
    loop (x:xs) set =
        if x `member` set
            then loop xs set
            else x : loop xs (insert x set)

하스켈, 나는 대체 사용 sequence, mapM, forM, replicateM,와 filterM. 이러한 작업은 각각 목록을 생성하지만 작업이 완전히 완료 될 때까지 (IO와 같은 엄격한 모나드를 사용하는 경우) 목록을 사용할 수 없습니다. 대안은 적어도 GHC를 사용하여 벤치마킹을 통해 더 빠른 것으로 나타났습니다.

sequence' :: Monad m => [m a] -> m [a]
sequence' ms = loop ms [] >>= return . reverse where
    loop []     xs = return xs
    loop (m:ms) xs = do
        x <- m
        loop ms (x:xs)

mapM' :: Monad m => (a -> m b) -> [a] -> m [b]
mapM' f xs = sequence' $ map f xs

forM' :: Monad m => [a] -> (a -> m b) -> m [b]
forM' = flip mapM'

replicateM' :: Monad m => Int -> m a -> m [a]
replicateM' n x = sequence' (replicate n x)

filterM' :: Monad m => (a -> m Bool) -> [a] -> m [a]
filterM' pred xs = loop xs [] >>= return . reverse where
    loop []     xs' = return xs'
    loop (x:xs) xs' = do
        keep <- pred x
        loop xs (if keep then (x:xs') else xs')

참고 : sequence_, mapM_, forM_, 그리고 replicateM_당신이 결과 목록에 관심이없는 경우 기능은 여전히 더 나은 선택입니다.


CCAN의 경우 +1, 약간 편향된 것으로 간주 될 수 있음 :)
Tim Post

4

ala Perl이없는 언어로 split / join을 구현하는 것을 마무리합니다.

나는 또한 생각하고 싶은 것보다 (내장 시스템 정크) C에서 atoi와 itoa를 다시 구현했습니다.


4

아니.

Java로 코딩 작업을 수행하는 것이 가장 좋으며 Apache Commons 라이브러리 및 유사한 프로젝트에서 "utils"를 재사용하는 것이 가장 좋습니다.

그것에 대해 객관적인 경우, 자신의 "utils"컬렉션이 다른 사람들이 이미 수행 한 작업을 크게 개선하는 경우는 거의 없습니다. 그리고 그것이 개선이 아니라면, utils 라이브러리는 아마도 개발 시간을 낭비하고 미래의 관리자에게 성가신 것입니다.


3

Java를 사용하여 수행 한 날짜 조작이 있었지만 JodaTime 을 사용하기 시작 했으며 Java 7에 포함될 좋은 것들을 들었습니다. 잘 사용할 가치가 있습니다).

약 3 개의 체인 메서드 호출을 통해 50 개 이상의 회선 클래스를 한 회선으로 전환했습니다.

궁금한 점은 과거 n 주일 의 날짜를 얻는 것과 관련이 있습니다 ( 예 : 10 주 전 월요일의 판매량 등).

그리고 여기에 그 일부가 있습니다

public static DateTime getDayPreviousWeek(DateTime dt, DayOfWeek dayOfWeek, int n_weeks) {
       return dt.minusWeeks(n_weeks).dayOfWeek().setCopy(dayOfWeek.getDayAsString());
}

자바에는 확장 방법이 있습니까?
Kugel

아니, 그러나 나는 그것이 버전 7에서 그들을 얻을 수 있다고 생각합니다
NimChimpsky

2

utilsJava에서도 항상 일종의 패키지가 있지만 PHP utils 컬렉션이 가장 많이 사용됩니다. Java에는 좋은 라이브러리가 너무 많아서 이미 프로젝트에 라이브러리가 포함되어 있거나 누락 된 유틸리티 몇 개를 직접 디자인해야합니다. PHP 라이브러리는 프로젝트에 포함시키기를 너무 많이하는 경향이 있습니다.

나는 PHP에 대해이 기능을 좋아 하고 StackOverflow의 도움으로 세련되었습니다 ...

function getValueFromDotKey(&$context, $name) {
    $pieces = explode('.', $name);
    foreach ($pieces as $piece) {
        if (!is_array($context) || !array_key_exists($piece, $context)) {
            // error occurred
            return null;
        }
        $context = &$context[$piece];
    }
    return $context;
}

Java의 Apache BeanUtils와 유사하며 비슷한 용도로 사용하여 템플릿 언어의 양식 요소에 소스 배열에서 중첩 값을 가져 오거나 설정할 수있는 단일 키를 제공합니다.

$source = array('a' => array('b' => 5));

$val = getValueFromDotKey($source, 'a.b');

가되지 않도록 물론, PHP 인, 나는 가능한 경량 같은 방법을 유지하고 싶었 매우 BeanUtils만큼 풍부한 기능;)


2

스칼라 표준 라이브러리에는 가장 일반적으로 사용되는 고차 함수가 없습니다.

가장 자주 필요한 두 가지 기능 :

// #1: unfold
def unfold[T, R](init: T)(f: T => Option[(R, T)]): List[R] = f(init) match {
  case None => Nil
  case Some(r, v) => r :: unfold(v)(f)
}

// #2: zipWith
def zipWith[A, B, C](xs: List[A], ys: List[B])(f: (A, B) => C): List[C] = {
  (xs, ys).zipped.map(f)
}

1

현재는 없습니다. 나는 C를하고있을 때 하나를 가지고 있었지만 이제는 Java를 수행하므로 모든 표준 라이브러리와 Apache 프로젝트의 모든 장점을 고려할 때 더 이상 의미가 없습니다.

내 C 라이브러리에서 유용한 것 중 하나는 빠르고 유한 한 유한 상태 머신 구현이었습니다. 단 두 개의 문자열과 문자열 배열로 유한 상태 머신을 정의 할 수있었습니다. 규칙을 기준으로 문자열을 검사하는 데 사용할 수 있습니다 (예 : "4.6 자 길이, 첫 문자, 나머지 숫자"). 정규식을 사용할 수 있으면 완전히 무의미합니다.



1

나는 장고에서 같은 코드를 많이 쓰고 있다는 것을 알았습니다.이 공통적 인 일을 한 다음이 일반적인 일을하고 마침내 그 일반적인 일을하십시오. 기본적으로 데이터베이스에서 하나 이상의 항목을 가져 오거나 양식 결과를 저장하십시오.

이러한 것들 각각이 뷰에서 한 번만 발생하면 django 일반 뷰를 사용할 수 있습니다. 불행히도, 그것들은 실제로 작곡 할 수 없으며 여러 가지 작업을 순서대로 수행해야했습니다.

그래서 더 일반적인 뷰 라이브러리를 작성하여 작성했습니다.이 라이브러리는 먼저 관련 쿼리 세트 (또는 무엇이든)에서 작업 목록을 작성한 다음 목록을 뷰로 래핑하여 작동했습니다.

나는 여전히 손으로 몇 가지 견해를 써야하지만, 재사용 할 수있는 것이 많지 않을 정도로 복잡합니다. 모든 상용구는 일반 뷰 또는 뷰 데코레이터 (종종 데코 레이팅 된 일반 뷰)로 다른 곳에 착륙합니다. 일부 일반 핸들러는 다른 모든 것을 수행 할 수 있기 때문에 일반적으로 필자가 작성한 핸들러의 약 10 %가됩니다.


1

예, 그러나 도메인 별 관용구 구조 (게임 객체 별 컨테이너와 같은)에만 해당됩니다.

복잡한 것보다 간단한 유틸리티 도구이므로 아무것도 자랑스럽지 않습니다. 어쨌든 나는 독특한 사용자이므로 자랑 할 것이 없습니다.


1

STL sort및 functor 템플릿을 기반으로하는 C ++ 간접 정렬

간접 정렬이 필요한 경우 (원하는 출력이 순열 인덱스 인 경우) 데이터 정렬에서 발생 였지만 정렬 된 데이터 자체 는 아니 었음)이 여러 프로젝트에서 여러 번 나타났습니다. 나는 왜 STL이 그 구현을 제공하지 않는지 항상 궁금했다.

다른 하나는 C ++ 순환 벡터로 양수 및 음수 인덱스는 벡터 크기의 모듈로입니다 (따라서 정수 값은 벡터에 유효한 인덱스 임).


-4

Comp에서 Java 개발을 할 때 작은 유틸리티 패키지를 작성했습니다. 고등학교에서 과학 수업. 난 내 난수 생성기를 가장 자랑스럽게 생각합니다.

/**
* Returns a random integer.
*
* @returns    int    Random integer
*/
public static int getRandom()
{
    return 4; // Chosen by a fair dice roll.
              // Guaranteed to be random.
}

내 영감에 소품.


12
c'mon, xkcd ....
Darknight

2
중요하지 않습니다.
Josh K

1
귀하의 현재 투표가 -2로, 정말 중요하다고 생각합니다.
user7676

8
표절은 명백한 경우를 제외하고 가장 높은 형태의 아첨입니다.
Maxpm

5
downvote 버튼은 "이 답변은 유용하지 않습니다"라고 말합니다. 나는 "...하지만 확실히 재미있다"라는 추가 버튼이 필요하다고 생각합니다.
skajfes
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.