Як видалити порожні елементи з масиву?


284

У мене є такий масив

cities = ["Kathmandu", "Pokhara", "", "Dharan", "Butwal"]

Я хочу видалити порожні елементи з масиву і хочу наступний результат:

cities = ["Kathmandu", "Pokhara", "Dharan", "Butwal"]

Чи є такий спосіб, compactякий буде робити це без циклів?

Відповіді:


501

Є багато способів зробити це, один є reject

noEmptyCities = cities.reject { |c| c.empty? }

Ви також можете використовувати reject!, що змінить citiesна місці. Він повернеться citiesяк повернене значення, якщо він щось відхилив, або nilякщо відхилень не буде зроблено. Це може бути хиткою, якщо ви не будете обережні (спасибі ninja08 за те, що вказали на це у коментарях).


227
Або якщо ви віддаєте перевагу більш компактномуcities.reject!(&:empty?)
aNoble

53
хм, чому б і ні cities.reject!(&:blank?)? empty?призначений для масивів
Ніко

27
@Nico blank?доступний тільки через ActiveSupport. Стандартний Ruby використовує String#empty?: ruby-doc.org/core-1.9.3/String.html#method-i-empty-3F
Michael Kohl

24
rejectкраще, ніж reject!тому, що [].reject!(&:empty?)повертається nil, [].reject(&:empty?)повертається[]
konyak

17
стежте з відхиленням !. відхилити! поверне нуль, якщо в масив не буде внесено змін. Якщо ви хочете повернути масив, коли жодних змін не було, просто скористайтеся відхиленням без нахилу.
Нік Рез

164
1.9.3p194 :001 > ["", "A", "B", "C", ""].reject(&:empty?)

=> ["A", "B", "C"]

5
Я вважаю за краще використовувати .reject (&: blank?), Щоб уникнути
нульових

4
@RanGalili blank?- це вдалий вибір, але його railsметод, і це питання стосується простої ситуаціїruby
Swaps

83

Ось що для мене працює:

[1, "", 2, "hello", nil].reject(&:blank?)

вихід:

[1, 2, "hello"]

На Ruby 2.3.1 я отримую NoMethodError: "undefined method` blank? " для 1: Fixnum "намагається виконати це.
Том

1
@Tom blank? є специфічним методом Rails. Не існує в масиві для простого рубіну. Вам доведеться використовувати порожнє? або написати власний метод.
jpgeek

@jpgeek Дякую за роз’яснення, що у мене виникли проблеми, коли я розумію, що :blank?стосується Rails.
Том

Тому що NoMethodError: undefined method empty? for nil:NilClass, :blank? краще ніж:empty?
провулок

:blankпрацює краще, ніж :empty. Тому :emptyщо не працює дляnil
KBIIX

54

У своєму проекті я використовую delete:

cities.delete("")

5
елегантний! на жаль, не повертає залишився масив, але досить гладкий
Кевін

11
Array.delete є інтуїтивно зрозумілим. Він працює як .delete! (), Якщо такий метод існував. .Delete () функціонує безпосередньо на масиві деструктивно.
scarver2

41

Коли я хочу виправити такий масив, я використовую:

["Kathmandu", "Pokhara", "", "Dharan", "Butwal"] - ["", nil]

Це видалить усі порожні або нульові елементи.


1
Насправді відповідь The Tin Man краще, оскільки вона також видалить все, що відповідає об’єкту # порожнім? тобто nil, "", "\ n", "", "\ n \ r" і т. д. На відміну від прийнятої відповіді, вона також буде працювати без Rails.
суперлюмінація

24

Найбільш явне

cities.delete_if(&:blank?)

Це видалить і nilзначення, і значення порожнього string ( "").

Наприклад:

cities = ["Kathmandu", "Pokhara", "", "Dharan", "Butwal", nil]

cities.delete_if(&:blank?)
# => ["Kathmandu", "Pokhara", "Dharan", "Butwal"]

Видалення пунктуації та додавання двокрапки дає "Міста: видалити, якщо порожнє": D
хлопайте

2
blank - метод рубіну чи рейки?
Арнольд Роа

2
@ArnoldRoa Це метод Rails.
ПолМест

1
що робити, якщо між порожнім рядком є ​​пробіл?
Стівен Агілар

@StevenAguilar пробіл вважається довжиною 1 (тому що пробіл є символом). "" .пусто? => false
флегкс

23

Спробуйте це:

puts ["Kathmandu", "Pokhara", "", "Dharan", "Butwal"] - [""]

4
Це гладко і не повертається ""! Це відмінна хитрість ліл.
Шон Ларкін

2
["Катманду", "Покхара", "", "Дхаран", "Бутваль"] - [""] - у цьому випадку не працюватиме
Аджахонгір

2.0.0-p247: 001> ["Катманду", "Покхара", "", "Дхаран", "Бутваль"] - [""] => ["Катманду", "Покхара", "Дхаран", "Бутваль "] Здається, працює для мене. Як ви думаєте, чому це не працює?
Raels

1
@Raels, порожній рядок у цьому випадку не порожній. У ній є єдиний простір.
Чандраншу

1
@Chandranshu Я прошу відрізнятися. Я скопіював і вставив текст у редактор і виявив, що між цитатами немає місця, як ви запропонували. Якби було, то віднімання ["", ""] спрацювало б. Приклад суперлюмінації схожий і працює. Початковий запит полягав у видаленні "пустих елементів", а не "елементів, які є пробілами", а приклад пустого елемента показаний в ОП як "".
Raels

17

Використання reject:

>> cities = ["Kathmandu", "Pokhara", "", "Dharan", "Butwal"].reject{ |e| e.empty? }
=> ["Kathmandu", "Pokhara", "Dharan", "Butwal"]

13
Або, як було зазначено вище aNoble, reject(&:empty?).
му занадто короткий

Символ proc проходить повільніше в 1.8.7, ніж формат блоку. Це нарівні з тим, що я бачив у 1.9.2
Кейлі Вудс

Це добре, оскільки він видалить будь-який елемент, який відповідає Object # empty?, Наприклад, "\ n", "", nil, "\ n \ n \ n" тощо ...
надсвітні

5
nil.empty?бум-перерва!
Naveed

1
@AllenMaxwell @Naveed Якщо масив має нульові елементи, передують reject(&:empty?)з , compactнаприклад[nil, ''].compact.reject(&:empty?)
scarver2

14
cities.reject! { |c| c.blank? }

Причина ви хочете використовувати blank?більш empty?що порожній визнає нуль, порожні рядки і прогалини. Наприклад:

cities = ["Kathmandu", "Pokhara", " ", nil, "", "Dharan", "Butwal"].reject { |c| c.blank? }

все одно повернеться:

["Kathmandu", "Pokhara", "Dharan", "Butwal"]

І , закликавши empty?на " "повернеться false, який ви , ймовірно , хочете бутиtrue .

Примітка: blank?доступний лише через Rails, підтримує лише Ruby empty?.


11

Відповідей уже багато, але ось інший підхід, якщо ти в світі Рейки:

 cities = ["Kathmandu", "Pokhara", "", "Dharan", "Butwal"].select &:present?

4
present?походить від ActiveSupport. У ній немає тега Rails, і для цього потрібен додатковий дорогоцінний камінь для одного методу.
Майкл Коль

1
@Naveed, вам слід передбачити це "Якщо ви використовуєте RoR". Я не підкажу це, оскільки це все ще корисна інформація для новачків.
pixelearth

9

Ось ще один підхід для досягнення цього

ми можемо використовувати presenceзselect

cities = ["Kathmandu", "Pokhara", "", "Dharan", nil, "Butwal"]

cities.select(&:presence)

["Kathmandu", "Pokhara", "Dharan", "Butwal"]

2
Дякую за це. У " "моєму масиві були деякі елементи, які не були видалені методом відхилення. Вилучено ваш метод nil ""або " "елементи.
iamse7en

8

Ось рішення, якщо у вашому масиві змішані типи:

[nil,"some string here","",4,3,2]

Рішення:

[nil,"some string here","",4,3,2].compact.reject{|r| r.empty? if r.class == String}

Вихід:

=> ["some string here", 4, 3, 2]

5

Ви можете спробувати це

 cities.reject!(&:empty?)

3
можливо, мався на увазіcities.reject!(&:blank?)
xguox

2
 cities = ["Kathmandu", "Pokhara", "", "Dharan", "Butwal"].delete_if {|c| c.empty? } 

видалення та упорядкування буде дорогою операцією
Naveed


0

інший метод:

> ["a","b","c","","","f","g"].keep_if{|some| some.present?}
=> ["a","b","c","f","g"]

-2

Оновіть суворо з join&split

cities = ["Kathmandu", "Pokhara", "", "Dharan", "Butwal"]
cities.join(' ').split

Результатом буде:

["Kathmandu", "Pokhara", "Dharan", "Butwal"]

Зауважте, що це не працює з містом з пробілами


2
Виглядає дуже ризиковано!
msdundar

1
Це, безумовно, не вдасться, якщо у вас є місто на кшталт "Нью-Йорк" або "Науйоджі Акмене" :)
Петрас L
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.