#javascript #node.js #arrays #typescript #reduce
#javascript #node.js #массивы #typescript #уменьшить
Вопрос:
arr1 = [
{
"levelNumber": "2",
"name": "abc",
},
{
"levelNumber": "3",
"name": "abc"
},
{
"levelNumber": "3",
"name": "raks",
}
]
в моем результирующем массиве должны быть объекты с максимальным levelNumber, т.е. 3 в этом случае.
это должно выглядеть так:
resultArr = [
{
"levelNumber": "3",
"name": "abc"
},
{
"levelNumber": "3",
"name": "raks",
}
]
обратите внимание, что здесь levelNumber может быть любым..
пожалуйста, помогите мне с общим кодом nodejs, чтобы получить повторяющиеся объекты с максимальным значением
Комментарии:
1. Вы ищете максимальное значение и должны дублироваться? Или должно быть только максимальное значение?
Ответ №1:
Сначала вы можете найти максимальный уровень всех объектов в массиве, а затем отфильтровать массив
arr1 = [
{
"levelNumber": "2",
"name": "abc",
},
{
"levelNumber": "3",
"name": "abc"
},
{
"levelNumber": "3",
"name": "raks",
}
]
const maxLevel = String(Math.max(...arr1.map(obj => Number(obj.levelNumber))))
const maxLevelObjects = arr1.filter(obj => obj.levelNumber === maxLevel)
console.log(maxLevelObjects);
Комментарии:
1. Аргумент типа ‘string’ не может быть присвоен параметру типа ‘number’.ts(2345)
2. это вызывает у меня эту проблему
3. обновлено сообщение для приведения к Number, чтобы избежать ошибки ts
4. @nat если вы используете TS, то преобразуйте
levelNumber
его в число, прежде чем передавать егоMath.max
. Вот такconst maxLevel = String(Math.max(...arr1.map(obj => obj.levelNumber)))
5. да @transGLUKator смотрите мой ответ выше.
Ответ №2:
const data = [
{
"levelNumber": "2",
"name": "abc",
},
{
"levelNumber": "3",
"name": "abc"
},
{
"levelNumber": "3",
"name": "raks",
}
];
const levelNumbers = data.map((item) => parseInt(item.levelNumber));
const maxLevelNumber = Math.max(...levelNumbers).toString();
const highestLevelItems = data.filter((item) => item.levelNumber == maxLevelNumber);
console.log(highestLevelItems);
/* output
[
{ levelNumber: '3', name: 'abc' },
{ levelNumber: '3', name: 'raks' }
]
*/
Редактировать
Как @nat упомянул в комментарии:
если я добавлю еще один объект в массив,
name = 'raks amp; levelNumber = '4'
тогда он должен отображать максимальный levelNumber с этим конкретным именем. т.е.{ "levelNumber": "3", "name": "abc" }, { "levelNumber": "4", "name": "raks" }
Для достижения этого вам необходимо:
- сделайте
Set
из имен - создайте отдельный пустой массив для хранения конечного результата
- повторите описанный выше процесс для каждого имени и добавьте результат в массив
- возвращает полный результат
const data = [
{
"levelNumber": "2",
"name": "abc",
},
{
"levelNumber": "3",
"name": "abc"
},
{
"levelNumber": "3",
"name": "raks",
},
{
"levelNumber": "4",
"name": "raks",
},
{
"levelNumber": "5",
"name": "raks",
}
];
// 1.
const names = new Set(data.map((item) => item.name)); // Set is used to get only unique items
// 2.
const result = []; // For normal JS
// const result: Array<{levelNumber: string, name: string}> = []; // For TS
// 3.
names.forEach((name) => {
/* minify data (filter items with only particular name) e.g. [{levelNumber: '2', name: 'abc'}, {levelNumber: '3', name: 'abc'}] */
const minifiedData = data.filter((item) => item.name === name);
/* same process, now for minified array */
const levelNumbers = minifiedData.map((item) => parseInt(item.levelNumber));
const maxLevelNumber = Math.max(...levelNumbers).toString();
minifiedData.forEach((item) => {
if (item.levelNumber == maxLevelNumber)
result.push(item); // push every matching item (item with highest level) in final result
});
});
// 4.
console.log(result);
Комментарии:
1. Аргумент типа ‘string’ не может быть присвоен параметру типа ‘number’.ts(2345) const levelNumbers: строка[]
2. он выдает эту ошибку ниже кода ответа
3. итак, вы используете typescript. Я обновил свой ответ, чтобы он работал и в TS!
4. БОЛЬШОЕ СПАСИБО! вы дали объяснение!
5. Уже сделано .. еще раз спасибо! похоже, я не могу проголосовать, так как мне нужна минимальная репутация!
Ответ №3:
const arr1 = [
{
levelNumber: '2',
name: 'abc',
},
{
levelNumber: '3',
name: 'abc',
},
{
levelNumber: '3',
name: 'raks',
},
];
const getHighLevelElements = (array) => {
if (array.length === 0) return null;
array.sort((elem1, elem2) => {
if (Number(elem1.levelNumber) < Number(elem2.levelNumber)) {
return 1;
}
if (Number(elem1.levelNumber) > Number(elem2.levelNumber)) {
return -1;
}
return 0;
});
return array.filter((elem) => elem.levelNumber === array[0].levelNumber);
};
const resultArr = getHighLevelElements([...arr1]);
console.log(resultArr);
Комментарии:
1. его отображение всех трех почему? @Lior Kamisnky
2. он отображает только только levelNumber: 3 элемента — попробуйте запустить фрагмент кода
Ответ №4:
Сначала я бы вызвал переменную highestLevel
для хранения самого высокого номера уровня, найденного в массиве объектов (будет использоваться позже при циклировании), перебираю весь массив и проверяю каждый ключ levelNumber
и сохраняю это число, если highestLevel
оно меньше значения текущего объекта levelNumber
. После того, как я перебрал массив и получил фактическое highestLevel
число, я бы снова прошел цикл и получил только те объекты, которые эквивалентны моей переменной highestLevel
Ответ №5:
Вы можете просто выполнить итерацию один раз arr1
с помощью Array.prototype.reduce()
Код:
const arr1 = [{levelNumber: '2',name: 'abc',},{levelNumber: '3',name: 'abc',},{levelNumber: '3',name: 'raks'}]
const result = arr1.reduce((a, c) => !a.length || c.levelNumber === a[0].levelNumber
? [...a, c]
: c.levelNumber > a[0].levelNumber
? [c]
: a,
[])
console.log(result)
Комментарии:
1. хорошее решение, но совсем не эффективное, потому что эта строка […a, c] будет копировать весь существующий массив на каждой итерации