Удалить дубликаты из массива объектов в jsonnet - PullRequest
0 голосов
/ 28 ноября 2018

У меня есть массив объектов, я хотел бы удалить дубликаты.В моем массиве есть общее поле name, которое я хотел бы использовать для дедупликации.

Я пытаюсь преобразовать массив в карту, а затем из карты обратно в массив, но преобразование карты выдает ошибку duplicate field name: "a":

local arr = [ 
    { "name": "a", "value": 1234},
    { "name": "b", "value": 555},
    { "name": "c", "value": 0}, 
    { "name": "a", "value": 1234} 
];
local map = { [x.name] : x  for x in arr };

Желаемый вывод:

[ 
      { "name": "a", "value": 1234},
      { "name": "b", "value": 555}, 
      { "name": "c", "value": 0} 
]

Ответы [ 2 ]

0 голосов
/ 29 ноября 2018

Как указал @seh в канале ksonnet , последний выпуск jsonnet теперь позволяет использовать std.set() для объектов.

 local arr = [
    { name: "a", value: 1234 },
    { name: "b", value: 555 },
    { name: "c", value: 0 },
    { name: "a", value: 1234 },
  ];
 std.set(arr, function(o) o.name)

Заголовок std.set() задокументирован в реализация std lib в jsonnet .

0 голосов
/ 28 ноября 2018

Игнорирование исходного порядка сортировки

Вы можете реализовать его, заменив понимание на std.foldl(), при этом обратите внимание на проблему с порядком:

local arr = [
  { name: "a", value: 4321 },
  { name: "b", value: 555 },
  { name: "c", value: 0 },
  { name: "a", value: 1234 },
];

// Use foldl to iterate from array, can't use comprehension because of dup fields
local map = std.foldl(function(x, y) x { [y.name]: y }, arr, {});

// Re-convert map to array, note that it'll not respect original order
// but fields' (ie 'name' key)
[ map[x] for x in std.objectFields(map)]

Сохранение исходного порядка сортировки

Если вам нужно сохранить исходный порядок сортировки в выходном массиве, вы можете добавить поле _idx для использования в окончательном sort():

local arr = [
  { name: "a", value: 4321 },
  { name: "b", value: 555 },
  { name: "c", value: 0 },
  { name: "a", value: 1234 },
];

// Overload array elements with there index (`_idx` field)
local idxArray = std.mapWithIndex(function(i, x) x { _idx:: i }, arr);

// Use foldl to iterate from array, can't use comprehension because of dup fields
local map = std.foldl(function(x, y) x { [y.name]: y }, idxArray, {});

// Re-convert map to array, it'll keep original order via added _idx field
std.sort([map[x] for x in std.objectFields(map)], function(e) e._idx)
...