Skip to content

Object.keys, values, entries #155

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -10,19 +10,19 @@ function sumSalaries(salaries) {
}

let salaries = {
"John": 100,
"Pete": 300,
"Mary": 250
"Іван": 100,
"Петро": 300,
"Марія": 250
};

alert( sumSalaries(salaries) ); // 650
```
Or, optionally, we could also get the sum using `Object.values` and `reduce`:
Або ж ми можемо також отримати суму, використовуючи `Object.values` та `reduce`:

```js
// reduce loops over array of salaries,
// adding them up
// and returns the result
// reduce перебирає масив значень salaries,
// складає їх
// і повертає результат
function sumSalaries(salaries) {
return Object.values(salaries).reduce((a, b) => a + b, 0) // 650
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,21 @@ importance: 5

---

# Sum the properties
# Підсумуйте властивості

There is a `salaries` object with arbitrary number of salaries.
Є об’єкт `salaries` з довільною кількістю властивостей, що містять заробітні плати.

Write the function `sumSalaries(salaries)` that returns the sum of all salaries using `Object.values` and the `for..of` loop.
Напишіть функцію `sumSalaries(salaries)`, що повертає суму всіх зарплат за допомогою `Object.values` та циклу`for..of`.

If `salaries` is empty, then the result must be `0`.
Якщо об’єкт `salaries` порожній, тоді результат повинен бути `0`.

For instance:
Наприклад:

```js
let salaries = {
"John": 100,
"Pete": 300,
"Mary": 250
"Іван": 100,
"Петро": 300,
"Марія": 250
};

alert( sumSalaries(salaries) ); // 650
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,19 @@ importance: 5

---

# Count properties
# Порахуйте властивості

Write a function `count(obj)` that returns the number of properties in the object:
Напишіть функцію `count(obj)`, що повертає кількість властивостей об’єкта:

```js
let user = {
name: 'John',
name: 'Іван',
age: 30
};

alert( count(user) ); // 2
```

Try to make the code as short as possible.

P.S. Ignore symbolic properties, count only "regular" ones.
Намагайтеся зробити код якомога коротшим.

P.S. Ігноруйте символьні властивості, враховуйте лише “звичайні”.
70 changes: 35 additions & 35 deletions 1-js/05-data-types/09-keys-values-entries/article.md
Original file line number Diff line number Diff line change
@@ -1,86 +1,86 @@

# Object.keys, values, entries

Let's step away from the individual data structures and talk about the iterations over them.
Відійдемо від окремих структур даних і поговоримо про ітерації над ними.

In the previous chapter we saw methods `map.keys()`, `map.values()`, `map.entries()`.
У минулому розділі ми бачили методи `map.keys()`, `map.values()`, `map.entries()`.

These methods are generic, there is a common agreement to use them for data structures. If we ever create a data structure of our own, we should implement them too.
Ці методи є загальними, існує спільна згода використовувати їх для структур даних. Якщо ми створюватимемо власну структуру даних, нам слід їх також реалізувати.

They are supported for:
Вони підтримуються для:

- `Map`
- `Set`
- `Array`

Plain objects also support similar methods, but the syntax is a bit different.
Звичайні об’єкти також підтримують подібні методи, але синтаксис дещо інший.

## Object.keys, values, entries

For plain objects, the following methods are available:
Для простих об’єктів доступні наступні методи:

- [Object.keys(obj)](mdn:js/Object/keys) -- returns an array of keys.
- [Object.values(obj)](mdn:js/Object/values) -- returns an array of values.
- [Object.entries(obj)](mdn:js/Object/entries) -- returns an array of `[key, value]` pairs.
- [Object.keys(obj)](mdn:js/Object/keys) -- повертає масив ключів.
- [Object.values(obj)](mdn:js/Object/values) -- повертає масив значень.
- [Object.entries(obj)](mdn:js/Object/entries) -- повертає масив пар `[ключ, значення]`.

Please note the distinctions (compared to map for example):
Зверніть увагу на відмінності (порівняно з map, наприклад):

| | Map | Object |
|-------------|------------------|--------------|
| Call syntax | `map.keys()` | `Object.keys(obj)`, but not `obj.keys()` |
| Returns | iterable | "real" Array |
| Синтаксис виклику | `map.keys()` | `Object.keys(obj)`, а не `obj.keys()` |
| Повертає | ітерабельний | "реальний" масив |

The first difference is that we have to call `Object.keys(obj)`, and not `obj.keys()`.
Перша відмінність полягає в тому, що ми повинні викликати `Object.keys(obj)`, а не `obj.keys()`.

Why so? The main reason is flexibility. Remember, objects are a base of all complex structures in JavaScript. So we may have an object of our own like `data` that implements its own `data.values()` method. And we still can call `Object.values(data)` on it.
Чому так? Основною причиною цього є гнучкість. Пам’ятайте, об’єкти є базою всіх складних структур у JavaScript. Ми можемо мати власний об’єкт, такий як `data`, який реалізує власний метод `data.values()`. І ми все ще можемо застосовувати до нього `Object.values(data)`.

The second difference is that `Object.*` methods return "real" array objects, not just an iterable. That's mainly for historical reasons.
Друга відмінність полягає в тому, що `Object.*` методи повертають "реальний" масив об’єктів, а не просто ітерабельний. Це переважно з історичних причин.

For instance:
Наприклад:

```js
let user = {
name: "John",
name: "Іван",
age: 30
};
```

- `Object.keys(user) = ["name", "age"]`
- `Object.values(user) = ["John", 30]`
- `Object.entries(user) = [ ["name","John"], ["age",30] ]`
- `Object.values(user) = ["Іван", 30]`
- `Object.entries(user) = [ ["name","Іван"], ["age",30] ]`

Here's an example of using `Object.values` to loop over property values:
Це приклад використання `Object.values` для перебору значень властивостей у циклі:

```js run
let user = {
name: "John",
name: "Іван",
age: 30
};

// loop over values
// Перебираємо значення
for (let value of Object.values(user)) {
alert(value); // John, then 30
alert(value); // Іван, тоді 30
}
```

```warn header="Object.keys/values/entries ignore symbolic properties"
Just like a `for..in` loop, these methods ignore properties that use `Symbol(...)` as keys.
```warn header="Object.keys/values/entries ігнорують символьні властивості"
Як і цикл `for..in`, ці методи ігнорують властивості, що використовують `Symbol(...)` як ключі.

Usually that's convenient. But if we want symbolic keys too, then there's a separate method [Object.getOwnPropertySymbols](mdn:js/Object/getOwnPropertySymbols) that returns an array of only symbolic keys. Also, there exist a method [Reflect.ownKeys(obj)](mdn:js/Reflect/ownKeys) that returns *all* keys.
Зазвичай це зручно. Якщо ми хочемо враховувати символьні ключі також, то для цього існує окремий метод [Object.getOwnPropertySymbols](mdn:js/Object/getOwnPropertySymbols), що повертає масив лише символьних ключів. Також існує метод [Reflect.ownKeys(obj)](mdn:js/Reflect/ownKeys) , що повертає *усі* ключі.
```


## Transforming objects
## Трансформація об’єктів

Objects lack many methods that exist for arrays, e.g. `map`, `filter` and others.
У об’єктів немає багатьох методів, які є у масивів, наприклад `map`, `filter` та інші.

If we'd like to apply them, then we can use `Object.entries` followed by `Object.fromEntries`:
Якщо б ми хотіли їх застосувати, тоді б ми використовували `Object.entries` з подальшим викликом `Object.fromEntries`:

1. Use `Object.entries(obj)` to get an array of key/value pairs from `obj`.
2. Use array methods on that array, e.g. `map`.
3. Use `Object.fromEntries(array)` on the resulting array to turn it back into an object.
1. Викликаємо `Object.entries(obj)`, щоб отримати масив пар ключ/значення з `obj`.
2. На ньому використовуємо методи масиву, наприклад `map`.
3. Використаємо `Object.fromEntries(array)` на отриманому масиві, щоб перетворити його знову на об’єкт.

For example, we have an object with prices, and would like to double them:
Наприклад, у нас є об’єкт з цінами, і ми б хотіли їх подвоїти:

```js run
let prices = {
Expand All @@ -91,12 +91,12 @@ let prices = {

*!*
let doublePrices = Object.fromEntries(
// convert to array, map, and then fromEntries gives back the object
// перетворити на масив, потім застосувати map, а потім fromEntries повертає об’єкт
Object.entries(prices).map(([key, value]) => [key, value * 2])
);
*/!*

alert(doublePrices.meat); // 8
```

It may look difficult at first sight, but becomes easy to understand after you use it once or twice. We can make powerful chains of transforms this way.
З першого погляду це може здатися важким, але стане зрозумілим після того, як ви використаєте це декілька разів. Таким чином ми можемо створювати потужні ланцюги перетворень.