Фильтрация вложенного массива - JavaScript

1

У меня есть вложенный массив, и каждый массив имеет строку и целое число, строки в одном из массивов одинаковы, но я хочу фильтровать массив, чтобы он содержал только вложенные массивы с уникальными именами и которые имеют самые высокие значения. Вот пример того, что у меня есть и чего я хочу:

[['a', 1],['a', 2],['a', 3],['b',2],['b',5]]

то, что я хочу сделать, это фильтр, чтобы он содержал это:

[['a', 3],['b', 5]]

Я изначально пытался сделать это с помощью цикла for и оператора if, а затем для цикла while и while, когда я смотрел на фильтрацию, но я не уверен, как реализовать его там, где он будет поддерживать строку с наивысшим значением, пожалуйста Помогите!!!!

  • 0
    пожалуйста, добавьте то, что вы пробовали.
Теги:
multidimensional-array
filter

5 ответов

3
Лучший ответ

Вы можете взять Map для группировки по первому элементу и получить максимальные значения, проверив сохраненные значения.

var array = [['a', 1], ['a', 2], ['a', 3], ['b', 2], ['b', 5]],
    result = Array.from(
        array.reduce((m, [k, v]) => m.set(k, m.has(k) ? Math.max(v, m.get(k)) : v), new Map)
    );
    
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Если вы хотите сохранить исходные массивы, вы можете сохранить массив вместо значения и принять позже только значения карты.

var array = [['a', 1], ['a', 2], ['a', 3, 'bar'], ['b', 2], ['b', 5, 'foo']],
    result = Array.from(array
        .reduce(
            (m, a) => m.has(a[0]) && m.get(a[0])[1] > a[1] ? m : m.set(a[0], a),
            new Map
        )
        .values()
    );
    
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
0
const obj = [['a', 1],['a', 2],['a', 3],['b',2],['b',5]].reduce((res, arr) => {
    res[arr[0]] = !res[arr[0]] ? arr[1] : Math.max(res[arr[0]], arr[1])
    return res
}, {})
const result = Object.keys(obj).map((key) => [key, obj[key]])
  • 2
    Как вы, скорее всего, знаете, размещение только кода без объяснения того, как работает ваш код, не является хорошей практикой. Краткий обзор кода очень поможет учащимся (например, автору вопроса).
0
const data = [['a', 1],['a', 2],['a', 3],['b',2],['b',5]]
const buf = {}
data.map(arr => {
    if(!buf[arr[0]] || buf[arr[0]] < arr[1])
        buf[arr[0]] = arr[1]
})
const result = Object.keys(buf).map(k => [k, buf[k]]);
console.log(result)
  • 0
    пожалуйста, объясните свой ответ
  • 0
    @Rafael выполняет итерацию данных, используя карту и сохраняя ключ и максимальное значение для буфера объекта. после этого создайте правильный массив результатов из объекта buf. так как другие ответы используют сокращение, я намеревался показать другое решение.
Показать ещё 3 комментария
0
const data = [['a', 1],['a', 2],['a', 3],['b',2],['b',5]];
var result = data.sort(function(a,b){
    return Math.max(b[1]-a[1]);
});
var new_data= result.slice(0,2);
console.log(new_data.reverse());
0

Вот решение с использованием сокращений и Object.keys и map.

const data = [['a', 1],['a', 2],['a', 3],['b',2],['b',5]];

//in reducer we work with object instead of array
//efficient since we avoid doing an extra loop
const result = data.reduce((acc, cur)=>{

  //create variables from current array (ex: ['a', 1])
  const letter = cur[0];
  const value = cur[1];

  //Acc (accumulator) holds the highest values (ex {a: 1, b: 2} )
  //If the letter doesn't yet exist or if the cur value is higher we update the acc
  if(!acc[letter] || acc[letter] < value){
    acc[letter] = value;
  }
  
  return acc;
}, {});

//Not in the correct format, so we transform the result into the requested format
const final = Object.keys(result).map(key=>[key, result[key]]);

console.log(final);
  • 0
    оно работает!! Спасибо!! Вы не могли бы объяснить мне это подробно?
  • 0
    Я бы порекомендовал пометить решение Нины stackoverflow.com/a/52755737/3589092 как правильный ответ. Это намного лучше, чем у меня.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню