Batalkan sisipan baris log [duplikat]
Anda mewarisi server yang menjalankan beberapa aplikasi yang semuanya menghasilkan log yang sama.
Tugas Anda adalah untuk memisahkan baris dari file log berdasarkan sumber. Untungnya, setiap baris dimulai dengan tag yang menunjukkan aplikasi asalnya.
Log
Setiap baris akan terlihat seperti ini:
[app_name] Something horrible happened!
- Tag aplikasi selalu berada di antara tanda kurung siku dan hanya akan berisi karakter alfanumerik dan garis bawah.
- Semua baris akan memiliki tag aplikasi di awal. Tidak akan ada spasi sebelumnya atau karakter lainnya.
- Akan selalu ada setidaknya satu spasi setelah tag aplikasi
- Tag aplikasi tidak kosong
- Mungkin nanti ada tanda kurung siku lain di baris mana pun.
- Mungkin ada atau mungkin tidak ada pesan setelah tag
- Log mungkin kosong
- Tidak ada batasan berapa banyak tag aplikasi unik yang akan ada di file.
Contoh
Seluruh log mungkin terlihat seperti ini:
[weather] Current temp: 83F
[barkeep] Fish enters bar
[barkeep] Fish orders beer
[stockmarket] PI +3.14
[barkeep] Fish leaves bar
[weather] 40% chance of rain detected
Yang seharusnya menghasilkan tiga log berbeda:
[weather] Current temp: 83F
[weather] 40% chance of rain detected
[barkeep] Fish enters bar
[barkeep] Fish orders beer
[barkeep] Fish leaves bar
[stockmarket] PI +3.14
Anda tidak akan diberi nama tag aplikasi sebelumnya. Anda harus menentukannya hanya dengan menganalisis file log.
Aturan dan Penilaian
- Ini adalah kode-golf , jadi kode terpendek menang.
- Aturan dan celah standar berlaku
- Gunakan format IO yang nyaman, asalkan setiap baris masukan direpresentasikan sebagai string, bukan tag + pesan yang telah diuraikan sebelumnya. Daftar tidak lengkap dari keluaran yang diizinkan:
- Beberapa file diberi nama setelah setiap tag
- Beberapa daftar string
- Satu daftar rangkaian string berisi baris yang dikelompokkan berdasarkan tag dengan atau tanpa pemisah (pemisah tidak boleh dimulai dengan tag)
- Sama seperti di atas, tetapi untuk stdout atau file.
- Urutan keluaran log yang terpisah tidak relevan, namun baris log dalam setiap grup harus mempertahankan urutan seperti yang ditemukan di file asli
Jawaban
R , 50 46 byte
function(r)split(r,substr(r,1,regexpr("]",r)))
Output sebagai a list
dengan setiap elemen name
d dengan [tag]
. Setiap elemen daftar mempertahankan urutan di dalam tagnya. Mengembalikan daftar nama named list()
kosong untuk input kosong.
-2 byte masing-masing berkat Robin Ryder dan Dominic van Essen!
Pyth , 3 byte
ohc
Format masukan adalah daftar string:
["[weather] Current temp: 83F","[barkeep] Fish enters bar","[barkeep] Fish orders beer","[stockmarket] PI +3.14","[barkeep] Fish leaves bar","[weather] 40% chance of rain detected"]
Bagaimana kode bekerja:
o
: Dipesan olehh
: Elemen pertama daric
: Setiap string dipisahkan menjadi spasi
Python , 44 byte
lambda a:sorted(a,key=lambda l:l.split()[0])
I / O longgar memungkinkan kita untuk mengambil, dan menghasilkan, daftar baris. Karena kita tidak harus memisahkan grup, masalahnya dikurangi menjadi jenis garis yang stabil pada awalan setiap baris hingga spasi pertama, split()
akan terpecah pada beberapa karakter spasi juga tetapi tidak ada yang dapat ditampilkan di bagian tag aplikasi.
APL (Dyalog Extended) , 10 byte ( SBCS )
Fungsi awalan diam-diam anonim. Mengambil daftar daftar karakter sebagai argumen. Mengembalikan matriks daftar karakter, dengan satu log di setiap baris.
⊢⊢⌸⍨≠⊃⍤⊆¨⊢
⊢
pada argumen,
≠
gunakan non-spasi untuk…
⊆¨
partisi setiap daftar menjadi daftar daftar (menghapus spasi, tetap menjalankan non-spasi),
⊃⍤
kemudian pertahankan yang pertama [dari masing-masing] (yaitu tag),
⊢⌸⍨
gunakan itu sebagai kunci untuk mengelompokkan…
⊢
argumen
vim, 13 11 byte
:sor/\w\+/r
perbaikan bug dan penyimpanan byte berkat @Dingus!
Scala, 26 byte
_.sortBy(_.split("]")(0))
Mengembalikan a List[String]
tanpa pemisah di antaranya, tetapi diurutkan berdasarkan tag.
Mengembalikan a Map[String,List[String]]
, 26 byte
_ groupBy(_.split("]")(0))
Mengambil daftar string dan mengembalikan di Map[List[String]]
mana kuncinya adalah tag dan nilainya adalah log yang terkait dengan tag itu.
Solusi sebelumnya, 66 byte
_ groupBy{case s"[$t]$r"=>t}map(_._2 mkString "\n")mkString "\n"*2
Cobalah di Scastie (untuk alasan apa pun, s
tidak berfungsi di TIO)
Setiap log aplikasi dipisahkan oleh 2 baris baru (saya mungkin dapat menghemat 2 byte jika itu hanya menjadi satu karakter baris baru). Inputnya adalah daftar string, dan outputnya adalah satu string besar.
05AB1E , 3 byte
Σ#¬
Input dan Output adalah daftar log.
Penjelasan:
Σ#¬
Σ Sort by:
# Split (each log) by spaces
¬ Head (which is the tagname)
Ini juga menjaga urutan log, sesuai kebutuhan.
Retina 0.8.2 , 14 13 byte
O$`(\w+).*
$1
Cobalah secara online! Penjelasan: Karena tidak diperlukan pemisah grup keluaran, garis-garis tersebut hanya diurutkan berdasarkan tag aplikasi, yang diperoleh dengan menangkap kecocokan \w+
dan menetapkannya $1
sebagai kunci pengurutan. Urutan di Retina stabil, sehingga baris dengan awalan yang sama akan mempertahankan urutannya. Edit: Disimpan 1 byte berkat @FryAmTheEggman karena menunjukkan cara yang lebih mudah untuk mencocokkan tag aplikasi. Perhatikan bahwa meskipun pertandingan tidak menyertakan awalan [
, semua baris dimulai dengan [
, jadi itu tidak memengaruhi hasil pengurutan.
AWK , 62 58 byte
Menyimpan 4 byte berkat Dominic van Essen !!!
{a[$1][i++]=$0}END{for(k in a)for(j in a[k])print a[k][j]}
Menyimpan semua baris dalam array asosiatif 2D a
. Kunci pertama adalah kolom pertama (dipisahkan oleh spasi). Jadi semua baris yang dimulai dengan bidang yang sama disimpan bersama. Kunci kedua adalah indeks integer yang meningkat. Bagian yang paling bertele-tele adalah END
tindakan yang mencetak konten yang a
dikelompokkan berdasarkan kolom pertama dalam urutan tampilan.
Io , 73 byte
method(i,i map(split first)unique map(I,i select(split first==I))flatten)
Perl 6 , 16 byte
*.sort:{~m/\w+/}
Mengurutkan berdasarkan string pertama karakter alfanumerik, yang seharusnya merupakan nama aplikasi
Python 3 , 148127 byte
a={}
try:
while 1:
b=input();c=b.split("]")[0]
if 1-(c in a):a[c]=[]
a[c]+=[b]
except:[print(e)for k in a for e in a[k]]
V (vim) , 5 byte
úr/?]
Catatan: Yang di ?
atas menggantikan byte yang tidak dapat dicetak \$\text{\x}81\$ (karakter kontrol "No Break Here").
Perhatikan bahwa ini berfungsi dengan kurangnya spasi (bahkan satu spasi langsung setelah tanda ]
kurung pertama ), dengan adanya []
tanda kurung di pesan log, dan dengan adanya aplikasi tanpa tanda, Cobalah secara online!
Bagaimana?
úr/?]
ú - sort by:
r - with flag=r: use match (default behaviour is to use what's after the match)
/ - with the pattern:
? - (byte 83) a shortcut for .\{-}
. - match any character
\{-} - 0 or more times matching as few times as possible
] - match a literal ']' character
AutoHotkey, 74 byte
Loop,Read,f
{
s:=A_LoopReadLine
FileAppend,%s%`n,% StrSplit(s,"]","[")[1]
}
Membaca dari file bernama f
dan menghasilkan beberapa file berdasarkan tag.
SimpleTemplate 0,84, 109 byte
Ya, itu cukup panjang, tapi berhasil!
{@callexplode intoL EOL,argv.0}{@eachL}{@if_ matches"@^(\[.*\])@"M}{@setS.[M.1]S.[M.1],_,EOL}{@/}{@/}{@echoS}
Kode ini menghasilkan array dengan <old content>, line, <end of line>
.
{@echoS}
secara otomatis meratakan array dan menampilkannya.
Ungolfed:
Ya, memang berantakan, tapi ini versi yang lebih bersih:
{@call explode into lines EOL, argv.0}
{@set storage null}
{@each lines as line}
{@if line matches "@^(\[.*\])@" match}
{@set storage.[match.1] storage.[match.1], line, EOL}
{@/}
{@/}
{@echo storage}
Fungsinya explode
adalah fungsi PHP standar, tetapi dapat diakses dari bahasa saya.
Anda dapat mencobanya di: http://sandbox.onlinephpfunctions.com/code/9c66f8bacc6315ae56e7c193170e430f9cf9d902
C # (NET Core) , 181 162 160 bytes
input.GroupBy(l=>l.Split()[0]).ToList().ForEach((g)=>{using(var sw = new StreamWriter(g.Key.Trim('[').Trim(']')+".log")){foreach(var v in g)sw.WriteLine(v);}});
C # (Visual C # Interactive Compiler) , 179 byte
i=>i.GroupBy((l)=>{return l.Split(' ')[0];}).ToList().ForEach((g)=>{using(var sw = new StreamWriter(g.Key.Trim(new char[]{'[',']'})+".log")){foreach(var v in g)sw.WriteLine(v);}})
Saya tidak yakin solusi pertama sesuai dengan code gulf, jadi solusi kedua menggunakan ekspresi lambda.
Rust, 40 byte
|a|a.sort_by_key(|x|x.split("]").next())
Mengambil referensi yang bisa berubah ke sepotong string dan mengurutkannya.
Perl 5 -M5.10.0 -Msort = stabil, 53 byte
say sort{(split('\]',$a))[0]cmp(split('\]',$b))[0]}<>