المسارات
/
jq
jq
/
المنهج
/
الكائنات
ال

الكائنات في jq

4 تمارين

نبذة عن الكائنات

الكائن في JSON هو ما يسمّى، بمصطلحات اللغات الأخرى، "hash" أو "map" أو "dictionary".

يعرّف JSON الكائن بأنه:

الكائن مجموعة غير مرتّبة من أزواج الاسم/القيمة. يبدأ الكائن بـ { قوس معقوف أيسر وينتهي بـ } قوس معقوف أيمن. ويتبع كل اسم : نقطتان، وتُفصل أزواج الاسم/القيمة عن بعضها بـ , فاصلة.

يجب أن يكون الاسم سلسلة نصية. وهناك كلمة أخرى مرادفة لـ_الاسم_ هي المفتاح.

يمكن أن تكون القيمة من أي نوع من أنواع JSON. ويمكن أن تكون القيم المختلفة في الكائن نفسه من أنواع مختلفة، كما في هذا المثال.

{
  "name": "Jane",
  "age": 42,
  "pets": ["cat", "fish"],
  "address": {"street": "123 Main St", "city": "Springfield"}
}

لاحظ أنه يجب ألا توجد فاصلة بعد زوج المفتاح/القيمة الأخير.

إنشاء الكائنات

استخدم الأقواس المعقوفة لتجميع أزواج الاسم/القيمة. ومع أن الأسماء يجب أن تكون سلاسل نصية، فإنها لا تحتاج إلى وضعها بين علامتي تنصيص إذا كانت شبيهة بالمعرّفات (مكوّنة من أحرف وأرقام وشرطة سفلية، ولا تبدأ برقم).

{name: "Jane", age: 42}

من الصحيح استخدام مفاتيح ليست شبيهة بالمعرّفات. فقط ضعها بين علامتي تنصيص.

{"first name": "Jane", "last name": "Lopez", age: 42}

إذا كان الاسم ناتجًا عن تعبير، فيجب أن يوضع التعبير بين الأقواس الهلالية.

$ echo "Jane" | jq -Rc '{.: 42}'
jq: error: syntax error, unexpected '.' (Unix shell quoting issues?) at <top-level>, line 1:
{.: 42}
jq: error: May need parentheses around object key expression at <top-level>, line 1:
{.: 42}
jq: 2 compile errors

$ echo "Jane" | jq -Rc '{(.): 42}'
{"Jane":42}

صيغ مختصرة

هناك حالتان متكررتان في بناء الكائنات لهما صيغة مختصرة.

  1. إعادة استخدام أزواج المفتاح/القيمة من كائن مُدخل.

    $ jq -n '$ENV | {USER: .USER, EDITOR: .EDITOR}'
    {
      "USER": "glennj",
      "EDITOR": "vim"
    }
    

    $ENV كائن يحمل أزواج الاسم/القيمة الخاصة بالبيئة.

    ويمكن كتابة الأزواج المتكرّرة key: .key على هيئة key فقط

    $ jq -n '$ENV | {USER, EDITOR}'
    {
      "USER": "glennj",
      "EDITOR": "vim"
    }
    
  2. وبالمثل، هناك صيغة مختصرة عند استخدام المتغيرات.

    $ jq -cn '"foo" as $a | "bar" as $b | {a: $a, b: $b}'
    {"a":"foo","b":"bar"}
    
    $ jq -cn '"foo" as $a | "bar" as $b | {$a, $b}'
    {"a":"foo","b":"bar"}
    

الفهرسة

تُستخرج القيم من الكائن باستخدام تدوين النقطة.

{name: "Jane", age: 42} | .age    # => 42

وإذا لم تستطع الإشارة إلى المفتاح كمعرّف، فاستخدم تدوين الأقواس المربعة.

"name" as $key | {name: "Jane", age: 42} | .$key    # => error
"name" as $key | {name: "Jane", age: 42} | .[$key]  # => "Jane"

وإذا لم يكن المفتاح موجودًا في الكائن، فالناتج هو null.

{name: "Jane", age: 42} | .sport  # => null

فهرسة القيم المتداخلة

ستكتشف أن هذا إجراء ستحتاج إلى تكراره مرارًا وتكرارًا عند تحليل النتائج التي تعيدها استعلامات API.

عندما يكون لدينا كائن يحتوي على قيم من نوع مصفوفة أو كائن، يمكننا "تسلسل" تعبيرات الفهرسة معًا.

{
  "name": "Jane",
  "age": 42,
  "pets": ["cat", "fish"],
  "address": {"street": "123 Main St", "city": "Springfield"}
}
| (
  .pets[1],       # => "fish"
  .address.city   # => "Springfield"
)

إضافة أزواج المفتاح/القيمة أو تغييرها

لإضافة زوج مفتاح/قيمة جديد إلى مصفوفة، أو لتحديث قيمة مفتاح موجود، استخدم عامل الإسناد =، مع تعبير فهرسة على الجانب الأيسر.

{name: "Jane", age: 42} | .sport = "tennis" | .age = 21
# => {
#      "name": "Jane",
#      "age": 21,
#      "sport": "tennis"
#    }

عامل + يدمج الكائنات.

{Richard: 54} + {Jane: 42}
# => {
#      "Richard": 54,
#      "Jane": 42
#    }

إزالة مفتاح

استخدم الدالة del لإزالة مفتاح. وهي تُرجع الكائن المحدَّث.

{name: "Jane", age: 42} | del(.age)   # => {"name": "Jane"}

المعامل الذي تمرّره إلى del هو تعبير فهرسة (بتدوين النقطة أو الأقواس المربعة) يشير إلى مفتاح في الكائن. ويسمّيه jq تعبير مسار. ولا يكفي أن تعطي سلسلة نصية فقط.

{name: "Jane", age: 42} | del(name)        # error: name/0 is not defined
{name: "Jane", age: 42} | del("name")      # error: Invalid path expression with result "name"
{name: "Jane", age: 42} | del(.name)       # OK
{name: "Jane", age: 42} | del(.["name"])   # OK

العضوية

  • لاختبار ما إذا كان الكائن يحتوي على مفتاح، استخدم الدالة has.

    {name: "Jane", age: 42} as $example
    |
      ($example | has("name")),    # => true
      ($example | has("sport"))    # => false
    
  • اختبر وجود مفتاح في كائن باستخدام in.

    {name: "Jane", age: 42} as $example
    |
      ("name"  | in($example)),    # => true
      ("sport" | in($example))     # => false
    

سرد المفاتيح أو القيم

استخدم الدالة keys لإخراج قائمة بكل المفاتيح.

{name: "Jane", age: 42} | keys   # => ["age", "name"]

لاحظ أن keys ترتّب المفاتيح. ولجلب المفاتيح بالترتيب الأصلي، استخدم keys_unsorted.

لا توجد دالة مكافئة لسرد كل القيم. لكن المرشّح .[] يُخرج قيم الكائن على هيئة تدفق، ويمكن التقاط هذا التدفق باستخدام مُنشئ المصفوفة [...].

[{first: "Jane", last: "Lopez", status: "awesome!"} | .[]]
# => ["Jane", "Lopez", "awesome!"]

التكرار

  • تطبّق الدالة map_values(filter) المرشّح على كل قيمة في الكائن.

    {first: "Jane", last: "Lopez", status: "awesome!"}
    | map_values(ascii_upcase)
    # => {"first": "JANE", "last": "LOPEZ", "status": "AWESOME!"}
    
  • للتكرار على كائن، يجب أولًا تحويله إلى مصفوفة من كائنات المفتاح/القيمة. وهذا ما تفعله الدالة to_entries.

    {name: "Jane", age: 42} | to_entries
    # => [
    #      {
    #        "key": "name",
    #        "value": "Jane"
    #      },
    #      {
    #        "key": "age",
    #        "value": 42
    #      }
    #    ]
    

    عند هذه النقطة، يمكننا استخدام دوال التكرار على المصفوفات، مثل map.

  • الدالة from_entries هي العكس: تحوّل مصفوفة من كائنات المفتاح/القيمة إلى كائن.

    [
      {"key":"name", "value":"Jane"},
      {"key":"age", "value":42}
    ] | from_entries                  # => {"name": "Jane", "age": 42}
    
  • لتطبيق مرشّح على كل زوج مفتاح/قيمة في كائن، استخدم الدالة with_entries(filter).

    على سبيل المثال، إذا كان لدينا كائن يربط بين اسم وعمر، فيمكن تبديل المفاتيح والقيم على النحو التالي.

    {"Jane": 42, "Richard": 54}
    | with_entries({key: (.value | tostring), value: .key})
    

    فيكون الناتج

    {
      "42": "Jane",
      "54": "Richard"
    }
    

    والدالة with_entries(filter) تكافئ

    to_entries | map(filter) | from_entries
    
تعديل عبر GitHub يفتح الرابط في نافذة أو علامة تبويب جديدة

تعلّم الكائنات

التدريب مقفل

افتح 4 تمارين إضافية لممارسة الكائنات