Powershell: функция запаздывания над свойством - PullRequest
1 голос
/ 01 марта 2020

Привет всем,

Я смотрю, есть ли возможность реализовать функцию задержки - без необходимости перебирать весь список, например, посмотрите на следующий пример:

$input = '[
    { "user_id":"1", "earned":"100", "valid_at": "20200101"},
    { "user_id":"1", "earned":"200", "valid_at": "20200102"},
    { "user_id":"1", "earned":"10", "valid_at": "20200103"},
    { "user_id":"2", "earned":"10", "valid_at": "20200101"},
    { "user_id":"2", "earned":"40", "valid_at": "20200103"},
    { "user_id":"3", "earned":"400", "valid_at": "20200101"},
    { "user_id":"3", "earned": null, "valid_at": "20200102"},
    { "user_id":"3", "earned": "20", "valid_at": "20200103"}
]'

$expected_output = '[
    { "user_id":"1", "earned":"100", "valid_at": "20200101", "last_earned":null},
    { "user_id":"1", "earned":"200", "valid_at": "20200102", "last_earned":"100"},
    { "user_id":"1", "earned":"10", "valid_at": "20200103", "last_earned":"200"},
    { "user_id":"2", "earned":"10", "valid_at": "20200101", "last_earned":null},
    { "user_id":"2", "earned":"40", "valid_at": "20200103", "last_earned":"10"},
    { "user_id":"3", "earned":"400", "valid_at": "20200101", "last_earned":null},
    { "user_id":"3", "earned": null, "valid_at": "20200102", "last_earned":"400"},
    { "user_id":"3", "earned": "20", "valid_at": "20200103", "last_earned":null}
]'

$json_input = ConvertFrom-Json –InputObject $input

$expected_json_output = ConvertFrom-Json –InputObject $expected_output

Это создает следующий ввод:

enter image description here

Вместе со следующим ожидаемым выводом:

enter image description here

Теперь мои вопросы таковы:

  • Есть ли способ программно построить столбец last_earned без необходимости перебирать весь список (т. Е. как-то с Group-Object или Where-Object?
  • В настоящее время я перебираю весь список - но мне пришлось быстро осознать, что, хотя он и работает, как ожидалось, он очень неэффективен, если у вас много записей для вычисления этого по
  • В настоящее время я вычисляю это отдельно для каждого отдельного user_id (т. е.
    • выбирая его,
    • упорядочивая результат, а затем
    • проверка последних заработанных

1 Ответ

1 голос
/ 02 марта 2020

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

$last = @{}
$json_input |Select-Object *,@{Name='earned_day_before';Expression={$last[$_.user_id];$last[$_.user_id]=$_.earned}}

Если нет Вы можете отсортировать все записи сначала по идентификатору пользователя, а затем по дате:

$last = @{}
$json_input |Sort-Object user_id,valid_at |Select-Object *,@{Name='earned_day_before';Expression={$last[$_.user_id];$last[$_.user_id]=$_.earned}}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...