Получение ошибки при добавлении вложенной хеш-таблицы в массив в Powershell

У меня есть вложенная хеш-таблица с массивом, и я хочу просмотреть содержимое другого массива и добавить его во вложенную хеш-таблицу. Я пытаюсь создать блок сообщений Slack.

Вот вложенная хеш-таблица, которую я хочу добавить:

$msgdata = @{
    blocks = @(
        @{
            type = 'section'
            text = @{
                type = 'mrkdwn'
                text = '*Services Being Used This Month*'
            }
        }
        @{
            type = 'divider'
        }      
    )
}

$rows = [ ['azure vm', 'centralus'], ['azure sql', 'eastus'], ['azure functions', 'centralus'], ['azure monitor', 'eastus2'] ]
$serviceitems = @()

foreach ($r in $rows) {
    $servicetext = "*{0}* - {1}" -f $r[1], $r[0] 
    $serviceitems += @{'type'='section'}
    $serviceitems += @{'text'= ''}
    $serviceitems.text.Add('type'='mrkdwn')
    $serviceitems.text.Add('text'=$servicetext)
    $serviceitems += @{'type'='divider'}
}

$msgdata.blocks += $serviceitems

Код частично рабочий. Хэш-таблицы @{'type'='section'} и @{'type'='divider'} добавлены успешно. Попытка добавить вложенную хеш-таблицу @{'text' = @{ 'type'='mrkdwn' 'text'=$servicetext }} завершается с ошибкой:

Line |
  24 |      $serviceitems.text.Add('type'='mrkdwn')
     |                                   ~
     | Missing ')' in method call.

Я пробовал просматривать различные посты Powershell и не смог найти ни одного, подходящего для моей конкретной ситуации. Я новичок в использовании хеш-таблиц в Powershell.

Неправильный синтаксис для вызова метода, вы хотите: $serviceitems.text.Add('type', 'mrkdwn')

Mathias R. Jessen 11.05.2022 18:05

Кстати: $rows = [ ['azure vm', 'centralus'] ... также является синтаксической ошибкой, пожалуйста, исправьте это утверждение, чтобы не отвлекать.

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

Ответы 2

Примечание:

  • Этот ответ касается вашего вопроса как спросил, в частности проблем с синтаксисом.

  • Лучшее решение, которое обходит исходных проблем в пользу оптимизированного кода, см. в разделе полезный ответ zett42.


$serviceitems.text.Add('type'='mrkdwn') вызывает синтаксическую ошибку.

В целом говорит, ЕСЛИ $serviceitems.text относится к хеш-таблице (словарю), вам нужно либо:

  • синтаксис метода с разными аргументами, разделенными ,:
$serviceitems.text.Add('type', 'mrkdwn')
  • или синтаксис показатель (который незаметно перезапишет существующую запись, если она присутствует):
$serviceitems.text['type'] = 'mrkdwn'

PowerShell даже позволяет вам обращаться к записям хеш-таблицы (словаря) с помощью синтаксис доступа к членам (точечная запись):

$serviceitems.text.type = 'mrkdwn'

В вашем конкретном случае дополнительные соображения вступает в игру:

  • Вы обращаетесь к хеш-таблице через массив, а не напрямую.

  • Запись text, на которую вы пытаетесь настроить таргетинг, изначально не является вложенной хеш-таблицей, поэтому вы не можете вызвать для нее .Add(); вместо этого вы должны назначить ему хеш-таблицу новый.

Поэтому:

# Define an empty array
$serviceItems = @()

# "Extend" the array by adding a hashtable.
# Note: Except with small arrays, growing them with += 
#       should be avoided, because a *new* array must be allocated
#       every time.
$serviceItems += @{ text = '' }

# Refer to the hashtable via the array's last element (-1),
# and assign a nested hashtable to it.
$serviceItems[-1].text = @{ 'type' = 'mrkdwn' }

# Output the result.
$serviceItems
Ответ принят как подходящий

В дополнение к полезный ответ mklement0, который решает проблему с вашим существующим кодом, я предлагаю следующий рефакторинг с использованием встроенных хеш-таблиц:

$serviceitems = foreach ($r in $rows) {
    @{
        type = 'section'
        text = @{
            type = 'mrkdwn'
            text = "*{0}* - {1}" -f $r[1], $r[0]
        }
    }
    @{
        type = 'divider'
    } 
}

$msgdata.blocks += $serviceitems

Это выглядит намного чище и, следовательно, проще в обслуживании, на мой взгляд.

Пояснения:

  • $serviceitems = foreach ... записывает весь вывод (в поток успех) цикла foreach в переменную $serviceitems. PowerShell автоматически создает массив из вывода, что более эффективно, чем добавление в массив вручную с помощью оператора +=. Использование += PowerShell должно воссоздать массива нового размера для каждого добавления, потому что массивы на самом деле имеют фиксированный размер. Когда PowerShell автоматически создает массив, он внутри использует более эффективная структура данных.
  • Записывая встроенную хэш-таблицу, не назначая ее переменной, PowerShell неявно выводит данные, фактически добавляя их в массив $serviceitems.
  • Мы выводим две хеш-таблицы на итерацию цикла, поэтому PowerShells добавляет два элемента массива в $serviceitems на итерацию цикла.

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