동일한 첫 번째 필드로 라인을 병합하는 Oneliner


15

이것은 첫 번째 코드 골프 질문이므로 적절하지 않은 경우 미리 사과하고 피드백을 환영합니다.

이 형식의 파일이 있습니다.

a | rest of first line
b | rest of second line
b | rest of third line
c | rest of fourth line
d | rest of fifth line
d | rest of sixth line

실제 내용은 구분자와 마찬가지로 다양합니다. 내용은 단지 텍스트입니다. 구분 기호는 한 줄에 한 번만 나타납니다. 이 퍼즐의 경우 구분 기호를 자유롭게 변경할 수 있습니다 (예 : "%"를 구분 기호로 사용).

원하는 출력 :

a | rest of first line
b | rest of second line % rest of third line
c | rest of fourth line
d | rest of fifth line % rest of sixth line

나는 이것을 병합하기 위해 루비와 awk 스크립트를 이미 가지고 있지만 짧은 oneliner를 가질 수 있다고 생각합니다. 즉, 파이프 및 명령 행에서 다른 명령과 함께 사용할 수있는 단일 라이너. 나는 그것을 알아낼 수 없으며, 내 자신의 스크립트는 오랫동안 명령 줄에서 압축하는 것입니다.

가장 짧은 문자를 선호합니다. 입력을 반드시 정렬 할 필요는 없지만 첫 번째 필드와 일치하는 연속 행을 병합하는 데에만 관심이 있습니다. 첫 번째 필드와 일치하는 무제한 줄이 있습니다. 필드 1은 과일 이름, 고유 이름 등 무엇이든 될 수 있습니다.

(저는 MacOS에서 실행되므로 개인적으로 mac에서 실행되는 구현에 관심이 있습니다).


다음은 두 번째 예 / 테스트입니다. 공지 사항 "|" 구분자입니다. "|"앞의 공간 관련이 없으며 원한 경우 키의 일부로 간주해야합니다. 출력에서 "%"를 구분 기호로 사용하고 있지만 다시 구분 기호를 자유롭게 변경하십시오 (그러나 대괄호는 사용하지 마십시오).

입력:

why|[may express] surprise, reluctance, impatience, annoyance, indignation
whom|[used in] questions, subordination
whom|[possessive] whose
whom|[subjective] who
whoever|[objective] whomever
whoever|[possessive] whosever
who|[possessive] whose
who|[objective] whom

원하는 출력 :

why|[may express] surprise, reluctance, impatience, annoyance, indignation
whom|[used in] questions, subordination%[possessive] whose%[subjective] who
whoever|[objective] whomever%[possessive] whosever
who|[possessive] whose%[objective] whom

출력 시작 부분에 줄 바꿈이 허용됩니까?
mIllIbyte

원래 질문에 의견을 추가했습니다. 그리고 @ mIllIbyte, 개행은 나에게 중요하지 않습니다. 그러나 내 생각에는 빈 줄이 없으며 오류 검사가 없습니다. 모든 줄에 텍스트가 있고 최소한 첫 번째 열과 구분 기호가 있다고 가정합니다.
MichaelCodes 2016 년

테스트 사례로 판단하면 모든 키가 그룹화되었다고 가정하여 저장됩니까? 즉 ["A|some text", "B|other text", "A|yet some other text"],에 대한 키워드 A가 목록에 하나씩 있지 않기 때문에 테스트 할 입력 이 아닙니다.
Kevin Cruijssen 2016 년

모든 키가 그룹화되어 있다고 가정했습니다. 이론적으로는 고유 키처럼 취급되지는 않지만 나는 그렇지 않습니다.
MichaelCodes 2016 년

답변:


7

레티 나 , 17 바이트

  • @MartinEnder 덕분에 12 바이트 절약
  • @ jimmy23013 덕분에 1 바이트 절약

ISO 8859-1로 인코딩 된 바이트로 스코어링되었습니다.

입력 필드 구분 기호 ;대신 사용 합니다 |.

(?<=(.+;).+)¶\1
%

온라인으로 사용해보십시오.



2
@LeakyNun 둘러보기가 원자 적이기 때문에. 처음으로 둘러보기를 사용하면 줄의 전체 접두사를 캡처 한 후 정규식 엔진이 더 이상 추적하지 않습니다.
마틴 엔더

5

V , 16 13 바이트

òí^¨á«©.*úsî±

온라인으로 사용해보십시오!

당신은 말했다

구분자를 자유롭게 변경하십시오

그래서 |구분 기호로 선택 했습니다. 이것이 유효하지 않은 경우 알려 주시면 변경하겠습니다.

설명:

ò                #Recursively:
 í               #Search for the following on any line:
  ^¨á«©          #1 or more alphabetic characters at the beginning of the line
       .*        #Followed by anything
         ús      #Mark everything after this to be removed:
           î±    #A new line, then the first match again (one or more alphabetic characters)

1
알려주세요 ???
아웃 골퍼 에릭

@ ΈρικΚωνσταντόπουλος 예? 그게 문제입니까?
DJMcMayhem

이 퍼즐의 경우 구분 기호를 자유롭게 변경하십시오 ( 예 : "%"를 구분 기호로 사용).
Outgolfer 에릭 18

2
"|" 구분자는 괜찮습니다.
MichaelCodes 2016 년

@MichaelCodes 솔루션의 카운트 여부를 확인할 수 있도록 테스트 케이스를 더 추가 할 수 있습니까?
DJMcMayhem 2016 년

3

-0n, 2 + 43 = 45 바이트

s/
.*\|/%/g,print for/(.*\|)((?:
\1|.)*
)/g

데모:

$ perl -0ne 's/
> .*\|/%/g,print for/(.*\|)((?:
> \1|.)*
> )/g' <<EOF
> why|[may express] surprise, reluctance, impatience, annoyance, indignation
> whom|[used in] questions, subordination
> whom|[possessive] whose
> whom|[subjective] who
> whoever|[objective] whomever
> whoever|[possessive] whosever
> who|[possessive] whose
> who|[objective] whom
> EOF
why|[may express] surprise, reluctance, impatience, annoyance, indignation
whom|[used in] questions, subordination%[possessive] whose%[subjective] who
whoever|[objective] whomever%[possessive] whosever
who|[possessive] whose%[objective] whom

3

SQL (PostgreSQL), 43 72 바이트

COPY T FROM'T'(DELIMITER'|');SELECT a,string_agg(b,'%')FROM T GROUP BY A

이것은 PostgreSQL의 편리한 string_agg 집계 함수를 활용합니다. 입력라는 테이블에서입니다 T2 열이 AB . 질문을 더 잘 준수하기 위해 파일에서 테이블로 데이터를로드하는 명령에 포함 시켰습니다. 파일 T도 있습니다. 테이블 작성 문을 세지 않았습니다.
출력이 정렬되지 않지만 문제가있는 경우에는ORDER BY A

SQLFiddle 은 나를 위해 놀고 싶지 않았지만 이것이 내 설정에서 얻는 것입니다.

CREATE TABLE T (A VARCHAR(9),B VARCHAR(30));

COPY T FROM'T'(DELIMITER'|');SELECT a,string_agg(b,'%')FROM T GROUP BY A
a   string_agg
--- ----------------------------------------
c   rest of fourth line
b   rest of second line%rest of third line
a   rest of first line
d   rest of fifth line%rest of sixth line

1
공평하게, 표에 지정된 파일 형식의 내용을 읽는 COPY 명령을 포함시키는 것이 좋습니다. 그렇지 않으면 다른 사람들과 동일한 문제를 해결하지 못합니다.
Jules

@ 줄스 페어 (Jules Fair), 나는 대답했을 때이 기본 I / O 컨센서스를 생각하고있었습니다 . 답변을 편집하지만 질문을 다시 읽습니다.
MickyT 2016 년

2

C, 127 바이트

o[99],n[99],p=n;main(i){for(;gets(n);strncmp(o,n,i-p)?printf(*o?"\n%s":"%s",n),strcpy(o,n):printf(" /%s",i))i=1+strchr(n,'|');}

gcc와 함께 작동합니다. 구분자를로 변경했습니다 /. stdin에서 입력을 가져 와서 stdout에 출력을 기록하므로 입력 리디렉션으로 호출./a.out <filename

언 골프 드 :

o[99],n[99] //declare int, to save two bytes for the bounds
,p=n; //p is an int, saves one byte as opposed to applying an (int) cast to n,
//or to declaring o and n as char arrays
main(i){for(;gets(n);strncmp(o,n,i-p //an (int)n cast would be needed;
// -(n-i) does not work either,
//because pointer arithmetics scales to (int*)
)?printf(*o?"\n%s":"%s" //to avoid a newline at the beginning of output
,n),strcpy(o,n):printf(" /%s",i))i=1+strchr(n,'|');}


1

파이썬 3-146 바이트

입력은 파일의 파일 이름 또는 파일 경로이며 출력은 stdout입니다. 커맨드 라인에서 원시 텍스트로 입력 할 수 있다면 훨씬 짧을 수 있습니다

stdin에서 입력을 stdin으로 출력합니다. 구분 기호로 설정하십시오 "|". 첫 번째 예제 입력을 테스트하려면 구분 기호를 사용하십시오." | "

from itertools import*
for c,b in groupby([x.split("|")for x in input().split("\n")],key=lambda x:x[0]):print(c,"|"," % ".join((a[1]for a in b)))

이 과제는 파일에서 입력을 명시 적으로 읽을 필요가 없으므로 기본 I / O 방법 이 여기에 적용되는 것 같습니다. 그리고 다른 답변도 STDIN의 입력을 받기 때문에 OP에 문제가 없다고 생각합니다.
Denker

@DenkerAffe 좋아, 내가 편집 할 것이다 .stdin에서 실제 여러 줄 입력을 줄 수도 있다고 생각하지 않기 때문에 완전히 쓸모가 없을 것이다.
Keatinge

그러나 스크립트를 실행할 때 입력 리디렉션을 수행 할 수 있습니다.
mIllIbyte

1

자바 7, 167 바이트

다른 접근법을 사용하여 골프를 더 많이 할 수 있습니다 ..

import java.util.*;Map c(String[]a){Map m=new HashMap();for(String s:a){String[]x=s.split("=");Object l;m.put(x[0],(l=m.get(x[0]))!=null?l+"%"+x[1]:x[1]);}return m;}

참고 : 위의 방법 HashMap은 원하는 키-값 쌍을 사용하여를 만들고 반환합니다 . 그러나 |키와 새 값 사이의 출력 구분 기호로 OP의 질문과 같이 정확한 출력으로 인쇄하지 않습니다 . 그가 MickeyT의 SQL 응답으로 판단 하면 데이터베이스 테이블을 반환했는데 이것이 가능하다고 생각했습니다. 인쇄 기능을 위해 더 이상 바이트가 추가되지 않아야합니다.

언 골프 및 테스트 코드 :

import java.util.*;

class Main{

    static Map c(String[] a){
        Map m = new HashMap();
        for(String s : a){
            String[] x = s.split("\\|");
            Object l;
            m.put(x[0], (l = m.get(x[0])) != null
                            ? l + "%" + x[1]
                            : x[1]);
        }
        return m;
    }

    public static void main(String[] a){
        Map m = c(new String[]{
            "why|[may express] surprise, reluctance, impatience, annoyance, indignation",
            "whom|[used in] questions, subordination",
            "whom|[possessive] whose",
            "whom|[subjective] who",
            "whoever|[objective] whomever",
            "whoever|[possessive] whosever",
            "who|[possessive] whose",
            "who|[objective] whom"
        });

        // Object instead of Map.EntrySet because the method returns a generic Map
        for (Object e : m.entrySet()){
            System.out.println(e.toString().replace("=", "|"));
        }
    }
}

산출:

whoever|[objective] whomever%[possessive] whosever
whom|[used in] questions, subordination%[possessive] whose%[subjective] who
why|[may express] surprise, reluctance, impatience, annoyance, indignation
who|[possessive] whose%[objective] whom

1

PowerShell, 85 바이트

문자열은 해시 테이블을 사용하여 병합됩니다.

%{$h=@{}}{$k,$v=$_-split'\|';$h.$k=($h.$k,$v|?{$_})-join'%'}{$h.Keys|%{$_+'|'+$h.$_}}

PowerShell은을 통한 stdin 리디렉션을 지원하지 않기 때문에 기본 I / O 방법으로 사용 <된다고 가정합니다 Get-Content .\Filename.txt |.

Get-Content .\Filename.txt | %{$h=@{}}{$k,$v=$_-split'\|';$h.$k=($h.$k,$v|?{$_})-join'%'}{$h.Keys|%{$_+'|'+$h.$_}}

산출

whoever|[objective] whomever%[possessive] whosever
why|[may express] surprise, reluctance, impatience, annoyance, indignation
whom|[used in] questions, subordination%[possessive] whose%[subjective] who
who|[possessive] whose%[objective] whom

1

APL, 42 자

{⊃{∊⍺,{⍺'%'⍵}/⍵}⌸/↓[1]↑{(1,¯1↓'|'=⍵)⊂⍵}¨⍵}

APL 인코딩에서 1 바이트가 아닙니다.
Zacharý

0

Sed, 55 바이트

:a N;:b s/^\([^|]*\)|\([^\n]*\)\n\1|/\1|\2 %/;ta;P;D;tb

시운전 :

$ echo """why|[may express] surprise, reluctance, impatience, annoyance, indignation
> whom|[used in] questions, subordination
> whom|[possessive] whose
> whom|[subjective] who
> whoever|[objective] whomever
> whoever|[possessive] whosever
> who|[possessive] whose
> who|[objective] whom""" | sed ':a N;:b s/^\([^|]*\)|\([^\n]*\)\n\1|/\1|\2 %/;ta;P;D;tb'
why|[may express] surprise, reluctance, impatience, annoyance, indignation
whom|[used in] questions, subordination %[possessive] whose %[subjective] who
whoever|[objective] whomever %[possessive] whosever
who|[possessive] whose %[objective] whom

0

q / kdb +, 46 바이트

해결책:

exec"%"sv v by k from flip`k`v!("s*";"|")0:`:f

예:

q)exec"%"sv v by k from flip`k`v!("s*";"|")0:`:f
who    | "[possessive] whose%[objective] whom"
whoever| "[objective] whomever%[possessive] whosever"
whom   | "[used in] questions, subordination%[possessive] whose%[subjective] who"
why    | "[may express] surprise, reluctance, impatience, annoyance, indignation"

설명:

`:f            // assumes the file is named 'f'
("s*";"|")0:   // read in file, assume it has two columns delimitered by pipe
flip `k`v      // convert into table with columns k (key) and v (value)
exec .. by k   // group on key
"%"sv v        // join values with "%"
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.