Oneliner để hợp nhất các dòng với cùng một trường đầu tiên


15

Đây là câu hỏi về codegolf đầu tiên của tôi, vì vậy tôi xin lỗi trước nếu nó không phù hợp và tôi hoan nghênh mọi phản hồi.

Tôi có một tập tin với định dạng này:

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

Các nội dung thực tế khác nhau, cũng như dấu phân cách. Các nội dung chỉ là văn bản. Dấu phân cách chỉ xuất hiện một lần trên mỗi dòng. Đối với câu đố này, vui lòng thay đổi dấu phân cách, ví dụ: sử dụng "%" làm dấu phân cách.

Sản phẩm chất lượng:

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

Tôi đã có cả hai tập lệnh ruby ​​và awk để hợp nhất điều này, nhưng tôi nghi ngờ có thể có một oneliner ngắn. tức là một lớp lót có thể được sử dụng cùng với các đường ống và các lệnh khác trên dòng lệnh. Tôi không thể tìm ra nó, và kịch bản của riêng tôi là dài để chỉ nén trên dòng lệnh.

Nhân vật ngắn nhất ưa thích. Đầu vào không nhất thiết phải được sắp xếp, nhưng chúng tôi chỉ quan tâm đến việc hợp nhất các dòng liên tiếp với các trường đầu tiên phù hợp. Có dòng không giới hạn với các trường đầu tiên phù hợp. Trường 1 có thể là bất cứ thứ gì, ví dụ như tên của các loại trái cây, tên riêng, v.v.

(Tôi chạy trên MacOS, vì vậy cá nhân tôi quan tâm nhất đến việc triển khai chạy trên mac).


Đây là một ví dụ / thử nghiệm thứ hai. Thông báo "|" là dấu phân cách Khoảng trắng trước dấu "|" là không liên quan, và nếu bực bội nên được coi là một phần của chìa khóa. Tôi đang sử dụng "%" làm giới hạn trong đầu ra, nhưng một lần nữa, vui lòng thay đổi dấu phân cách (nhưng không sử dụng dấu ngoặc vuông).

Đầu vào:

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

Sản phẩm chất lượng:

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

Là một dòng mới ở đầu ra cho phép?
mIllIbyte

thêm ý kiến ​​vào câu hỏi ban đầu. Và, @mIllIbyte, một dòng mới không liên quan đến tôi. Nhưng trong ý tưởng của tôi, không có dòng trống, và không có kiểm tra lỗi. Tôi giả sử tất cả các dòng có văn bản, và ít nhất là cột đầu tiên và dấu phân cách.
MichaelCodes

Đánh giá theo các trường hợp thử nghiệm, liệu có lưu để giả sử rằng tất cả các khóa được nhóm lại không? Tức ["A|some text", "B|other text", "A|yet some other text"]là : không phải là một đầu vào mong muốn để kiểm tra, vì các từ khóa Akhông phải là một từ khóa khác trong danh sách.
Kevin Cruijssen

Tôi giả sử tất cả các khóa được nhóm lại. Tôi không quan tâm đến trường hợp họ không, mặc dù về lý thuyết, không phải họ sẽ được đối xử như những chiếc chìa khóa độc nhất.
MichaelCodes

Câu trả lời:


7

Võng mạc , 17 byte

  • 12 byte được lưu nhờ @MartinEnder
  • Lưu 1 byte nhờ @ jimmy23013

Được ghi trong các byte được mã hóa ISO 8859-1.

Sử dụng ;thay vì |như dấu phân cách trường đầu vào.

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

Hãy thử trực tuyến.



2
@LeakyNun Bởi vì nhìn là nguyên tử. Lần đầu tiên sử dụng giao diện, nó sẽ ghi lại toàn bộ tiền tố của dòng và sau đó, công cụ regex sẽ không quay trở lại nữa.
Martin Ender

5

V , 16 13 byte

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

Hãy thử trực tuyến!

Bạn đã nói

Hãy thay đổi dấu phân cách

Vì vậy, tôi đã chọn |làm dấu phân cách. Nếu điều này không hợp lệ, hãy cho tôi biết và tôi sẽ thay đổi nó.

Giải trình:

ò                #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
Cho bạn biết ???
Erik the Outgolfer

@ ΈρκΚω Đó có phải là vấn đề không?
DJMcMayhem

Đối với câu đố này, vui lòng thay đổi dấu phân cách, ví dụ: sử dụng "%" làm dấu phân cách. không có nghĩa là
Erik the Outgolfer

2
"|" phân định là tốt.
MichaelCodes

@MichaelCodes Bạn có thể thêm một số trường hợp thử nghiệm để chúng tôi có thể xác minh xem một giải pháp có được tính hay không?
DJMcMayhem

3

Perl -0n, 2 + 43 = 45 byte

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

Bản giới thiệu:

$ 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 byte

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

Điều này tận dụng chức năng tổng hợp chuỗi_agg tiện dụng trong PostgreSQL. Đầu vào là từ một bảng được gọi Tvới 2 cột AB. Để tuân thủ câu hỏi tốt hơn, tôi đã đưa vào lệnh để tải dữ liệu từ một tệp vào bảng. Các tập tin là Ttốt. Tôi đã không đếm bảng tạo bảng.
Đầu ra sẽ không được sắp xếp, nhưng nếu đó là một vấn đề thì nó có thể được sửa bằngORDER BY A

SQLFiddle không muốn chơi cho tôi, nhưng đây là những gì tôi nhận được trong thiết lập của mình.

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
Để công bằng, tôi cũng đề nghị bao gồm lệnh COPY để đọc nội dung của định dạng tệp được chỉ định trong bảng, nếu không, bạn sẽ không giải quyết vấn đề tương tự như mọi người khác.
Jules

@Jules Đủ rồi, tôi đã nghĩ đến sự đồng thuận i / o mặc định này khi tôi trả lời. Đọc lại câu hỏi mặc dù tôi sẽ chỉnh sửa câu trả lời.
MickyT

2

C, 127 byte

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,'|');}

Hoạt động với gcc. Thay đổi dấu phân cách thành /. Đưa đầu vào từ stdin và ghi đầu ra vào thiết bị xuất chuẩn, vì vậy hãy gọi với chuyển hướng đầu vào./a.out <filename

Ung dung:

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

Pyth - 15 byte

Đưa ra một vài giả định về vấn đề, sẽ thay đổi khi OP làm rõ.

jm+Khhd-sdK.ghk

Hãy thử trực tuyến tại đây .


Điều này không hoạt động nếu "chìa khóa" là một từ, thay vì một chữ cái. (OP làm rõ trong các bình luận)
DJMcMayhem

1

Python 3 - 146 byte

Đầu vào là tên tệp hoặc đường dẫn tệp của tệp, đầu ra là xuất chuẩn. Có thể ngắn hơn rất nhiều nếu tôi có thể lấy đầu vào dưới dạng văn bản thô từ dòng lệnh

Đưa đầu vào từ stdin và đầu ra cho stdin. Thiết lập với dải phân cách "|". Để kiểm tra đầu vào ví dụ đầu tiên, sử dụng dấu phân cách" | "

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)))

Thách thức không rõ ràng yêu cầu đầu vào phải được đọc từ một tệp, vì vậy tôi đoán các phương pháp I / O mặc định của chúng tôi áp dụng ở đây. Và vì các câu trả lời khác cũng lấy đầu vào từ STDIN, tôi cho rằng OP vẫn ổn với nó.
Denker

@DenkerAffe Được rồi tôi sẽ chỉnh sửa nó, nó sẽ hoàn toàn vô dụng vì tôi không nghĩ bạn thậm chí có thể cung cấp đầu vào đa dòng thực tế từ stdin.
Keatinge

Nhưng bạn có thể thực hiện chuyển hướng đầu vào khi bạn chạy tập lệnh.
mIllIbyte

1

Java 7, 167 byte

Nó có thể được đánh gôn nhiều hơn bằng cách sử dụng một cách tiếp cận khác ..

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;}

LƯU Ý: Phương thức trên tạo và trả về a HashMapvới các cặp khóa-giá trị mong muốn. Tuy nhiên, nó không in nó trong đầu ra chính xác như trong câu hỏi của OP với |vai trò là dấu phân cách đầu ra giữa các khóa và các giá trị mới. Đánh giá bằng câu trả lời SQL của MickeyT khi anh ta trả lại bảng cơ sở dữ liệu tôi cho rằng điều này được cho phép; nếu không thêm byte thì nên thêm chức năng in.

Mã thử nghiệm & mã hóa:

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("=", "|"));
        }
    }
}

Đầu ra:

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 byte

Chuỗi được hợp nhất bằng cách sử dụng hashtable:

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

Thí dụ

Vì PowerShell không hỗ trợ chuyển hướng stdin thông qua <, tôi giả sử rằng nó Get-Content .\Filename.txt |sẽ được sử dụng làm phương thức I / O mặc định.

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

Đầu ra

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 ký tự

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

không phải là một byte trong mã hóa APL.
Zacharý

0

Sed, 55 byte

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

Chạy thử nghiệm :

$ 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 byte

Giải pháp:

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

Thí dụ:

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"

Giải trình:

`: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 "%"
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.