2016-09-08 21 views
5

Tôi đang làm việc với các sên cho thuốc nổ, ý tưởng là: Tôi có một chuỗi với [a-zA-Z0-9] các từ được phân tách bằng dấu gạch nối. Giống như:Làm thế nào để cắt ngắn một chuỗi trong elixir?

string = "another-long-string-to-be-truncated-and-much-text-here" 

Tôi muốn đảm bảo rằng chiều dài chuỗi tối đa bằng 30, nhưng tôi cũng muốn chắc chắn rằng các từ không bị cắt một nửa khi đạt đến độ dài tối đa. Vì vậy, 30 ký hiệu đầu tiên của stringanother-long-string-to-be-trun nhưng tôi muốn có another-long-string-to-be với từ truncated để được xóa hoàn toàn. Làm thế nào tôi có thể làm điều đó?

Trả lời

3

Phương pháp đơn giản nhất sẽ là:

"another-long-string-to-be-truncated-and-much-text-here" 
|> String.slice(0..29) 
|> String.replace(~r{-[^-]*$}, "") 
#⇒ "another-long-string-to-be" 

Có một trục trặc với nó: nếu gạch nối là chính xác vào vị trí 31, thuật ngữ cuối cùng sẽ bị xóa. Để tránh điều này, người ta có thể kiểm tra một cách rõ ràng để chơi bóng với điều kiện trên:

str = "another-long-string-to-be-truncated-and-much-text-here" 
case str |> String.at(30) do          
    "-" -> str |> String.slice(0..29)         
    _ -> str |> String.slice(0..29) |> String.replace(~r{-[^-]*$}, "") 
end                
#⇒ "another-long-string-to-be" 

hay:

orig = "another-long-string-to-be-cool-cated-and-much-text-here" 
str = orig |> String.slice(0..29) 
unless String.at(orig, 30) == "-", do: str = str |> String.replace(~r{-[^-]*$}, "") 
str 
#⇒ "another-long-string-to-be-cool" 
+0

Có một lỗi nhỏ ở đây: nếu chuỗi gốc chứa một từ dài hơn 30 ký tự, từ gốc được trả về. Điều này dẫn đến một chuỗi dài hơn 30 ký tự, tôi cho rằng nó sẽ trả về một chuỗi rỗng để thay thế. –

+0

@PatrickOscity nó hiện trả về từ này cắt ngắn đến 30 điểm. Trả về một chuỗi rỗng _as a slug_ nghe như một ... uhm thiết kế kém cho tôi. – mudasobwa

+0

vâng, đó là sự thật cho một con sên :) –

1

Bạn có thể làm điều đó một cách đệ quy ..

defmodule Truncation do 
    def truncate_words_to(str, max) do 
    length = String.length(str) 
    words? = Regex.match?(~r{-}, str) 
    cond do 
     length <= max -> str 
     words?  -> truncate_words_to(String.replace(str, ~r{-[^-]*$}, ""), 
             max) 
     true   -> String.slice(str, 0..(max-1)) 
    end 
    end 
end 
+0

'cond' không có ý nghĩa vì điều kiện' true' là hoàn toàn có thể áp dụng khi 'length <= max'. Người ta có thể sử dụng 'if' ở đó. – mudasobwa

+0

Đúng là 'String.slice' sẽ hoạt động nếu chuỗi đã ngắn hơn' max', nhưng chúng tôi vẫn cần kiểm tra 'length <= max' riêng biệt để tránh cắt một từ không cần thiết. Vì vậy, chúng tôi vẫn có ba trường hợp khác nhau: chuỗi đã đủ ngắn, chuỗi quá dài và chứa dấu nối, hoặc chuỗi quá dài và không chứa dấu nối. –

+0

Ah, vâng, hiểu rồi, xin lỗi. Câu hỏi bây giờ là nếu biểu tượng 'max'th là dấu gạch ngang thì sao? – mudasobwa

0

câu trả lời của tôi là dựa trên @mudasobwa câu trả lời, nhưng tôi quyết định đơn giản hóa nó rất nhiều

"another-long-string-to-be-truncated-and-much-text-here" 
|> String.slice(0..29) 
|> String.split("-") 
|> Enum.slice(0..-2) 
|> Enum.join("-") 

Đúng rồi!

+0

Điều này là vô nghĩa. Nó a) trả về một danh sách, b) thất bại trong trường hợp điểm 31 trong chuỗi là dấu gạch nối và c) ngụ ý sự ép buộc thừa vào/từ danh sách. – mudasobwa

+0

@mudasobwa a) bạn đúng Tôi đã quên tham gia b) Tôi không có kinh nghiệm thất bại c) nhưng thật dễ dàng để đọc thay vì – asiniy

+0

b) bạn có, nhưng bạn thích không thể hiểu nó. Hãy thử nó trên '" một chuỗi dài-nhiều-được-mát-cated-và-nhiều-văn bản-ở đây "'. Mã của bạn tạo ra '" một chuỗi dài-to-be' "khác, trong khi kết quả chính xác là' "một chuỗi dài-to-be-cool" '. Tôi đã mô tả trường hợp góc này trong đoạn cuối của câu trả lời của tôi. – mudasobwa

Các vấn đề liên quan