JSONiq подсчитывает дубликаты в массиве

Я хочу посчитать повторяющиеся значения с помощью JSONiq. У меня есть следующий код:

jsoniq version "1.0";

import module namespace fetch = "http://zorba.io/modules/fetch";

let $tweets := parse-json(fetch:content("/tweets.json"))
let $users := parse-json(fetch:content("/users.json"))

return 
    let $different_languages :=
        for $tweet in $tweets[]
        return {
            "name" : $tweet."metadata"."iso_language_code" 
        }


    return [$different_languages]

Это возвращает все языки, но открывает новую пару для каждого языка. Это выглядит так:

    [ { "name" : "de" }, 
      { "name" : "da" },
      { "name" : "da" },
      { "name" : "da" }]

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

    [ { "count" : 1, "language" : "de" }, 
      { "count" : 3, "language" : "da" }]

Как я могу достичь этого?

1 ответ

Решение

Это может быть достигнуто с помощью предложения group-by. Это работает как группа SQL, но с еще более высоким уровнем контроля.

В приведенном ниже коде четыре объекта в распакованном виде $tweets массивы сгруппированы в соответствии с их языковым полем ($tweet.metadata.iso_language_code). В каждой оценке предложения return переменная группировки $language будет содержать название языка для текущей группы и переменную без группировки $tweet будет содержать последовательность твитов, принадлежащих группе. призвание count() по этой последовательности вернет 3 и 1 соответственно.

jsoniq version "1.0";

import module namespace fetch = "http://zorba.io/modules/fetch";

let $tweets := parse-json(fetch:content("/tweets.json"))
let $users := parse-json(fetch:content("/users.json"))

return 
  for $tweet in $tweets[]
  group by $language := $tweet."metadata"."iso_language_code" 
  return { language: $language, count: count($tweet) }

Кроме того, цитаты на metadata а также iso_language_code не нужны. При необходимости вы можете также обернуть результат в массив, например так:

jsoniq version "1.0";

import module namespace fetch = "http://zorba.io/modules/fetch";

let $tweets := parse-json(fetch:content("/tweets.json"))
let $users := parse-json(fetch:content("/users.json"))

return [
  for $tweet in $tweets[]
  group by $language := $tweet.metadata.iso_language_code
  return { language: $language, count: count($tweet) }
]

Нет никаких ограничений на выражение в предложении возврата: $language а также $tweet переменные, как и любые другие, и они могут быть использованы в качестве входных данных для любого выражения JSONiq. Например, вместо подсчета твитов можно также вкладывать их в выходные данные, поскольку модель данных является древовидной:

return { language: $language, count: [ $tweet ] }
Другие вопросы по тегам