хотите отобразить все максимальные ‘levelNumber’ объектов в массиве

#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" }

Для достижения этого вам необходимо:

  1. сделайте Set из имен
  2. создайте отдельный пустой массив для хранения конечного результата
  3. повторите описанный выше процесс для каждого имени и добавьте результат в массив
  4. возвращает полный результат
 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] будет копировать весь существующий массив на каждой итерации