Странное поведение FINDW во встроенных циклах do?

Когда я использую цикл do для перебора массива слов в SAS и проверки их существования в строке, это работает. Когда я добавляю второй для ежедневных слов, FINDW не находит слова, уже находящиеся в конечной строке.

Итак, это работает так, как ожидалось:

word1 = ""
word2 = "pancake"
word3 = ""
word4 = "donut"
word5 = ""
array word {5} $ 250 word:;
final_str = "pancake";

do i = 1 to 5;
final_str_w_removed_hyphens = translate(final_str, " ", "-");

if findw(final_str_w_removed_hyphens,  word[i], " ") = 0 
     then final_str = catx("-", str, word[i]);

Это дает мне ожидаемую окончательную строку «блинчик-пончик».

Однако, когда я включаю дни в дело (каждый день может быть несколько названий завтраков), findw начинает вести этот странный двойной счет. Данные выглядят так, они описывают продукты, которые мы ели на завтрак в данный день:

breakfast_foods_jan1 | breakfast_foods_jan2                   | breakfast_foods_jan3                 | breakfast_foods_jan4               |
---------------------|----------------------------------------|--------------------------------------|------------------------------------|
"breakfast-pancake"  | "breakfast-donut-breakfast-pancake"    | "breakfast-donut-breakfast-pancake"  | "breakfast-donut-breakfast-pancake"|

Я хочу найти все уникальные продукты для завтрака, которые человек съел за год, вот мое решение:

do j=1 to 4          /*january 1st - january 4th*/;
      do i=1 to i=5 /*there can't be more than 5 breakfast items on any day*/;

            if scan(breakfast_foods[j], i, "-", "d") ne "breakfast"
              then daily_breakfast_foods[i] = scan(breakfast_foods[j], i, "-", "d");

            word_find = findw(translate(all_breakfast_foods, " ", "-"), daily_breakfast_foods[i], " ");

             if word_find=0 then all_breakfast_foods =
              catx("-", all_breakfast_foods, daily_breakfast_foods[i];

end;
end;

Это возвращает окончательный all_breakfast_foods «блин-пончик-блин», он дважды считает блин!!! Я понятия не имею, почему word_find не находит блин, когда он явно содержится в строке all_breakfast_foods.

Вот что происходит в цикле:

daily_breakfast_foods1 | daily_breakfast_foods2 |daily_breakfast_foods3 | daily_breakfast_foods4 | daily_breakfast_foods5 |
-----------------------|------------------------|-----------------------|-----------------------|------------------------|
                       | donut                  |                       |pancake               |                        |```

all_breakfast_foods_debug1 all_breakfast_foods_debug2 all_breakfast_foods_debug3 all_breakfast_foods_debug4 all_breakfast_foods_debug5 блин блин блин пончик блин пончик блин пончик блин

Просто ваш примерный список значений включает как «блин», так и «блин»? У второго есть ведущее место.

Tom 09.12.2022 16:34

@Tom хм... когда я меняю 5-ю строку в реальном примере на------------------------------------------------ ----------- то daily_breakfast_foods[i] = strip(scan(breakfast_foods[j], i, "-", "d")); это не решает проблему.

brown twelve 09.12.2022 16:42
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
2
54
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Исправление состояло в том, чтобы не раздеваться в строке 5, как я пытался. Мне пришлось добавить strip() в функцию findw в word_find в строке 8 как таковую:

 word_find = findw(translate(all_breakfast_foods, " ", "-"), STRIP(daily_breakfast_foods[i]), " ");

Ооооочень странно.

Ответ принят как подходящий

Таким образом, в вашем списке есть несколько начальных пробелов (пробелы после разделителя -), которые вызывают проблемы. Вы можете использовать функцию LEFT() для удаления начальных пробелов. И FINDW() имеет модификатор T для обрезки конечных пробелов при поиске слов.

Итак, давайте превратим ваш список тестовых данных в реальный набор данных.

data have ;
  input (breakfast_foods_jan1-breakfast_foods_jan4) ($40./);
cards;
breakfast-pancake
breakfast-donut-pancake
breakfast-donut-pancake
breakfast-donut- pancake
;

Теперь мы можем перебрать переменные еды, а затем перебрать каждый список продуктов и создать список уникальных продуктов.

data want;
  set have;
  array foods breakfast_foods_jan1-breakfast_foods_jan4 ;
  length next_food $30 food_list $200 ;
  do day=1 to dim(foods);
    do item=1 to countw(foods[day],'-');
      next_food = left(scan(foods[day],item,'-'));
      if next_food ne 'breakfast' then do;
        if not findw(food_list,next_food,'-','t') then
          food_list=catx('-',food_list,next_food)
        ;
      end;
    end;
  end;
  drop day item next_food;
run;

Результат:

Спасибо! Это работает. Хорошо, но если сделать массив из отсканированных слов. SAS не покажет вам начальные пробелы в этих переменных! Так сложно устранить неполадки.

brown twelve 09.12.2022 17:46

Как вы попросили SAS показать вам? Если вы распечатаете обычный текстовый список, вы увидите начальные пробелы. Но если вы печатаете в ODS, они «исчезают». Вы можете использовать формат $QUOTE с переменными для отображения значений внутри кавычек. Тогда ведущие пробелы более заметны. Также возможно, что ваши реальные данные имеют какой-то другой невидимый характер. В этом случае печать значений в формате $HEX покажет символы. '20'x - это пробел. '09'x - это табуляция.

Tom 09.12.2022 17:49

Я не хотел приводить полный пример... строки содержат количество съеденных за день продуктов. (т.е. пончик-1-блин-1), отсюда и разделитель "d" в findw. Я вижу, как возможно, что появляются дополнительные пробелы. Я постараюсь использовать $QUOTE, чтобы избежать этого в будущем.

brown twelve 09.12.2022 17:55

Другие вопросы по теме