当另一个数组有一个数字(值)时如何匹配2个数组的字符串值

Posted

技术标签:

【中文标题】当另一个数组有一个数字(值)时如何匹配2个数组的字符串值【英文标题】:How to match the string values of 2 arrays when the other array has a Number(value) 【发布时间】:2020-01-26 11:40:06 【问题描述】:

我是 javascript 新手。我试图获取数组(arr1)的Math.max(...arr1 [i] [1]),只有当它与第二个数组(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]

我知道我做错了什么,而且我别无选择。需要帮助。

【问题讨论】:

您的映射变量arr2.map 没有意义,您知道映射函数的作用吗? @Nard Pascua 我认为预期的输出是错误的,因为abandon-2, 1, -2,其中1 是最大的。所以请重新检查您的预期输出。 【参考方案1】:

您可以更好地直接使用Set 而不是arr2 之类的数组来查找匹配项,因为在Set 的情况下它将是恒定时间查找。

然后使用Array.prototype.filter 过滤数组arr1 并获取arr2 中的那些数组。

最后Array.prototype.reduce 将帮助您创建一个对象,其中键是单词,值是arr1 中该单词的最大值,您可以使用从reduce 返回的对象中的Object.entries 来获取二维数组形式的数据:

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 中。所以你可以使用下面编辑的sn-p:

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);

【讨论】:

非常感谢!稍后会尝试。 我尝试在浏览器上运行它,这确实有效!但是,我正在为这个作业开发一个nodeJS,似乎“.flat()”和“.has”不适用于我的nodeJS。但是,我碰巧为“.flat()”找到了另一种方法。所以,我现在唯一的问题是如何重构“映射”。我尝试了“hasOwnProperty”和“includes”,但它们不起作用。请指教。提前致谢! :) @LockandLock 请查看代码中的编辑和 cmets,了解使用数组的替代解决方案。【参考方案2】:

我会尽可能少地使用循环。

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));

【讨论】:

以上是关于当另一个数组有一个数字(值)时如何匹配2个数组的字符串值的主要内容,如果未能解决你的问题,请参考以下文章

比较2个数组并列出差异 - Swift

如何连接2个数组:1个数组包含字符串,另一个数组包含int64

比较 2 个数组并列出差异 - Swift

当另一个字段有反馈时,为啥 bootstrap-4 输入组会拉伸?

Perl:组合两个哈希数组的值并使第二个数组的值成为输出哈希的键

循环时向数组添加字段和值?