#javascript
#javascript
Вопрос:
У меня простая проблема, но решение для меня непросто. В принципе, у меня действительно есть массив с объектами состояния в нем.
status = [ {status:1, id:10},
{status:2, id:11},
{status:1, id:12}]
Теперь я хочу подсчитать все объекты со статусом 1, все объекты со статусом 2 за один раз. Итак, мой конечный результат должен быть примерно таким:
[ [1,2], [2,1]]
У меня уже есть это, но последний шаг для меня всегда завершается неудачей:
items = status.map(function(x){return x.status})
unique = new Set(items)
И тогда я застрял.
В python я знаю, как это сделать, но в данный момент это невозможно.
// this is the python code
items = [x["status"] for x in status]
[ [x, items.count(x)] for x in set(items)]
Комментарии:
1. Обязательно ли в результате получается массив? Вы можете легко использовать reduce для достижения такой цели, и, на мой взгляд, имело бы смысл вернуть объект вместо этого: jsfiddle.net/5ks9ph1n
2. Объект тоже подойдет
![]()
Ответ №1:
Вы могли бы взять a Map
и массив пар ключ / значение с Array.from
.
Кстати, вам нужно переименовать global status
во что-то другое, потому что window.status
это строка a, зарезервированная для сообщений о состоянии пользовательского агента.
var array = [{ status: 1, id: 10 }, { status: 2, id: 11 }, { status: 1, id: 12 }],
result = Array.from(array.reduce(
(m, { status }) => m.set(status, (m.get(status) || 0) 1),
new Map
));
console.log(result);
Комментарии:
1.
status.reduce is not a function
2. @Durga, откуда у вас ошибка? внутренняя
status
— это локальная переменная, внешняя — массив.3. В Chrome. После изменения внешнего статуса на что-то другое это работает.
4. @NinaScholz запуск примера выдает ошибку. prntscr.com/msz37f Хотя решение абсолютно правильное, оно выдает TypeError
5. возможно, переименование поможет.
Ответ №2:
const status = [
{status:1, id:10},
{status:2, id:11},
{status:1, id:12}
];
const statuses = [];
const result = [];
status.map(s => {
if (statuses.indexOf(s.status) === -1) {
result.push([ s.status, status.filter(i => i.status === s.status ).length ]);
statuses.push(s.status);
}
});
console.log(result);
Ответ №3:
Поскольку объект также является принятым ответом (как указано в комментариях выше), вы также можете просто использовать reduce
и переносить данные в новый объект:
var arr = [ {status:1, id:10},
{status:2, id:11},
{status:1, id:12}];
console.log(
arr.reduce((a, {status}) => {
if (a[status]) a[status] ;
else a[status] = 1;
return a;
}, {})
)
Вы все еще можете сократить количество шагов для выполнения чего-либо, хотя приведенное выше довольно легко прочитать. если в «a» (который является пустым объектом в начале) статус уже существует, затем увеличьте его. В противном случае установите его равным единице и продолжайте, пока массив не будет полностью зациклен.
{status}
(второй параметр) возвращает status
ключевое значение текущего зацикленного объекта, эквивалентное item.status
.
Ответ №4:
Вы можете просто использовать простой reduce
, а затем использовать записи, чтобы получить ожидаемый формат
const status = [ {status:1, id:10},
{status:2, id:11},
{status:1, id:12}];
const result = status.reduce((acc, {status}) => (acc[status] = (acc[status] || 0) 1, acc), {});
console.log(result);
const formattedResult = Object.entries(result)
console.log(formattedResult);
// If you need to remove the string format from the keys:
const formattedResult2 = Object.entries(result).map(([k,v]) => [Number(k),v]);
console.log(formattedResult2);
Комментарии:
1. Выходные данные не являются массивом массивов, как описано в вопросе.
2. Обновлено. Хотя ожидаемый результат для меня довольно неестественный!