Как сопоставить строковые значения 2-х массивов, когда другой массив имеет число (значение) - PullRequest
3 голосов
/ 26 сентября 2019

Я новичок в Javascript.Я пытаюсь получить Math.max (... arr1 [i] [1]) массива (arr1), только когда он совпадает со вторым массивом (arr2).Затем поместите его в массив (arr3), и результат не должен иметь повторяющихся значений.

Я попытался перебрать оба массива (arr1 и arr2), а затем использовал оператор if для их сопоставления.

var arr1 = [ [ 'abandon', -2 ],
[ 'abandon', 1 ],
[ 'abandon', -2 ],
[ 'abduct', 1 ],
[ 'abduct', -2 ],
[ 'abduct', -2 ],
[ 'abhor', -3 ],
[ 'abhor', 1 ],
[ 'abhor', -1 ],
[ 'abil', 2 ],
[ 'abil', 4 ] ];


var arr2 = [ [ 'abandon' ],
[ 'abil' ],
[ 'abhor' ],
[ 'abduct' ],
['test'],
['hey'],
['testAgain'],
['array']];

var arr3 = [];

const mapping = arr2.map(word => {
    return word
})

for(var i = 0; i < arr1.length; i++){

    if(arr1[i][0] === mapping){
        arr3.push(Math.max(...arr1[i][1]))
    }

}
let arr4 = [...new Set(arr3)]

//example result:

var arr4 = [[abandon, -2],
[abduct, -2],
[abhor, -3],
[abil, 4]... and so on]

Я знаю, что делаю что-то не так, и у меня нет выбора.Нужна помощь.

Ответы [ 2 ]

0 голосов
/ 26 сентября 2019

Я бы сделал как можно меньше циклов.

var arr1 = [ [ 'abandon', -2 ], [ 'abandon', 1 ], [ 'abandon', -2 ], [ 'abduct', 1 ], [ 'abduct', -2 ], [ 'abduct', -2 ], [ 'abhor', -3 ], [ 'abhor', 1 ], [ 'abhor', -1 ], [ 'abil', 2 ], [ 'abil', 4 ] ];

var arr2 = [ [ 'abandon' ], [ 'abil' ], [ 'abhor' ], [ 'abduct' ], ['test'], ['hey'], ['testAgain'], ['array']];


function getHighestResults(dataArr, filterArr) {
  var name = '';    // higher readability in code and created outside 
  var number = -1;  // for loops to avoid creating variables inside of them
  
  function existsInObject(obj, name) {
    return obj.hasOwnProperty(name);
  }
  
  function filterBasedOn(arr, obj) {
    var filteredArr = [];
    
    for (let i = 0; i < arr.length; i++) {
      name = arr[i][0];
      
      if (existsInObject(obj, name)) {
        filteredArr.push([name, obj[name]]);
      }
    }
    
    return filteredArr;
  }
  
  function getHighestValuesAsObj(arr) {
    var dataObj = {};

    for (let i = 0; i < arr.length; i++) {
      name = arr[i][0];
      number = arr[i][1];
  
      if (!existsInObject(dataObj, name) || dataObj[name] < number) {
        dataObj[name] = number;
      }
    }
    
    return dataObj;
  }
    
  return filterBasedOn(filterArr, getHighestValuesAsObj(dataArr));
}


console.log(getHighestResults(arr1, arr2));
0 голосов
/ 26 сентября 2019

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

Затем используйте Array.prototype.filter для фильтрации массива arr1 и получите те массивы, которые находятся в arr2.

Наконец, Array.prototype.reduce поможет вам создать объект, ключами которого являются слова, а значения являются наибольшим значением для этого слова в arr1, и вы можете использовать Object.entries из этого объекта, возвращенного из reduce чтобы получить данные в виде двумерного массива:

var arr1 = [ [ 'abandon', -2 ],
[ 'abandon', 1 ],
[ 'abandon', -2 ],
[ 'abduct', 1 ],
[ 'abduct', -2 ],
[ 'abduct', -2 ],
[ 'abhor', -3 ],
[ 'abhor', 1 ],
[ 'abhor', -1 ],
[ 'abil', 2 ],
[ 'abil', 4 ] ];


var arr2 = [ [ 'abandon' ],
[ 'abil' ],
[ 'abhor' ],
[ 'abduct' ],
['test'],
['hey'],
['testAgain'],
['array']];

var lookup = new Set(arr2.flat());
var mapping = arr1.filter(([word, val]) => lookup.has(word));
var data = Object.entries(mapping.reduce((acc, o, i) => {
    if(acc[o[0]]){
        acc[o[0]] = Math.max(o[1], acc[o[0]]);
    }else{
        acc[o[0]] = o[1];
    }
    return acc;
},{}));

console.log(data);

РЕДАКТИРОВАТЬ

Сформируйте свой комментарий Я предполагаю, что вы используете более старую версию среды выполнения узла, где flat() отсутствуетв Array.prototype.Таким образом, вы можете использовать отредактированный фрагмент ниже:

var arr1 = [ [ 'abandon', -2 ],
[ 'abandon', 1 ],
[ 'abandon', -2 ],
[ 'abduct', 1 ],
[ 'abduct', -2 ],
[ 'abduct', -2 ],
[ 'abhor', -3 ],
[ 'abhor', 1 ],
[ 'abhor', -1 ],
[ 'abil', 2 ],
[ 'abil', 4 ] ];


var arr2 = [ [ 'abandon' ],
[ 'abil' ],
[ 'abhor' ],
[ 'abduct' ],
['test'],
['hey'],
['testAgain'],
['array']];

//flatten using Array.prototype.concat
var lookup = new Set([].concat.apply([], arr2)); 
//If Set doesn't work use the array, but this will not be a constant time lookup
//var lookup = [].concat.apply([], arr2);  

var mapping = arr1.filter(([word, val]) => lookup.has(word));
//If you are not using Set and going with an array, use Array.prototype.includes, so search won't be O(1)
//var mapping = arr1.filter(([word, val]) => lookup.includes(word));

var data = Object.entries(mapping.reduce((acc, o, i) => {
    if(acc[o[0]]){
        acc[o[0]] = Math.max(o[1], acc[o[0]]);
    }else{
        acc[o[0]] = o[1];
    }
    return acc;
},{}));

console.log(data);
...