【问题标题】:Create new jQuery Array by Comparing a Single Value in Multiple Arrays通过比较多个数组中的单个值来创建新的 jQuery 数组
【发布时间】:2017-06-08 12:51:33
【问题描述】:

这方面有很多帖子,但是我的 JS 印章还没有找到适合我的情况的解决方案。

我有两个数组,一个是 Google Lat/Lng 变量的硬编码数组(屏幕截图中的 Array2),另一个是通过迭代 DOM 元素构造的数组(屏幕截图中的 Array1)。我需要将 Array2 与从 DOM 动态创建的 Array1 进行比较,并创建一个仅包含 Array1 中的 Array2 对象的新 Array3。这将是我迭代创建地图标记的数组。以下是我的代码示例。

数组1

var gdata = new Array();

$("table tbody tr:gt(0)").each(function (i) {
    gdata[i] = new Array();
    $(this).children('td').each(function (ii) {
        gdata[i][ii] = $(this).text();
    });
});

数组2

var markers = [
    ['a0', 32.840801, -117.244842],
    ['a10', 32.840801, -117.244842],
    ['a20', 32.840777, -117.244864],
    ...
]

【问题讨论】:

  • 匹配的应该是Array1第一列的文本,还是任意列的值?您是否需要 Array1 用于其他目的,或者我们可以提出另一种结构?
  • 是的,我可以将其移至第 1 列。
  • 不,不,这不是我要问的。所以匹配值可以在 HTML 表中的任何位置,而不仅仅是在第 1 列中?
  • @trincot 我只关心 [0] 位置,因为这是我的标记的 Lat/Lng 数组。两个目标对象现在都在 [0] 位置,并且已上传新的屏幕截图。希望这会让事情变得更容易。

标签: javascript jquery arrays


【解决方案1】:

由于您的检查似乎只处理 HTML 表第一列中的值,因此您无需阅读 gdata 中的所有内容,只需阅读第一列即可。然后,您可以将第一列中的文本转换为以文本为键的对象,这样可以更快地查找:

var gdata = {};
$("table tbody tr:gt(0)>td:first-child").each(function () {
    gdata[$(this).text()] = true;
});

var markers = [
    ['a0', 32.840801, -117.244842],
    ['a10', 32.840801, -117.244842],
    ['a20', 32.840777, -117.244864],
    ['c3', 32.840777, -117.244864],
];

var array3 = markers.filter(function(row) {
    return row[0] in gdata; 
});

console.log(array3);
td, th { font-size: 9px; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table cellspacing=0 cellpadding=0 border=1>
   <tr>
      <th>heading</th><th>heading</th><th>heading</th>
   </tr>
   <tr>
      <td>b</td><td>123</td><td>123</td>
   </tr>
   <tr>
      <td>a20</td><td>123</td><td>123</td>
   </tr>
   <tr>
      <td>a0</td><td>123</td><td>123</td>
   </tr>
</table>

如果你有 ES6 支持,你可以使用 Set 和箭头函数来代替:

var gdata = new Set($("table tbody tr:gt(0)>td:first-child")
                    .map( (i,td) => $(td).text()).get());

var markers = [
    ['a0', 32.840801, -117.244842],
    ['a10', 32.840801, -117.244842],
    ['a20', 32.840777, -117.244864],
    ['c3', 32.840777, -117.244864],
];

var array3 = markers.filter( ([id]) => gdata.has(id) );

console.log(array3);
td, th { font-size: 9px; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table cellspacing=0 cellpadding=0 border=1>
   <tr>
      <th>heading</th><th>heading</th><th>heading</th>
   </tr>
   <tr>
      <td>b</td><td>123</td><td>123</td>
   </tr>
   <tr>
      <td>a20</td><td>123</td><td>123</td>
   </tr>
   <tr>
      <td>a0</td><td>123</td><td>123</td>
   </tr>
</table>

【讨论】:

    【解决方案2】:

    我认为你应该使用类似的东西:

    var results = []; // the results array
    
    for (var i = 0; i < markers.length; i++) // iterate for every marker key
    {
       results = results.concat(gdata.filter(function(item) { return item[8] == markers[i][0]; }));
    }
    

    在 js 中,我们可以使用 filter 方法通过查询语句仅检索给定数组的一部分。在这种情况下,我们使用了每个标记键与整个 gdata 的比较数组.. 最后 - 我们将每个标记的相关项目连接到目标结果数组

    【讨论】:

    • 请添加一些解释为什么此代码有助于 OP。这将有助于为未来的观众提供一个可以从中学习的答案。请参阅How to Answer 了解更多信息。
    【解决方案3】:

    如果其中任何一个 (some()) 与动态列表匹配,听起来您想要 filter() 静态列表:

    var markers = [
        ['a0', 32.840801, -117.244842],
        ['a10', 32.840801, -117.244842],
        ['a20', 32.840777, -117.244864]
    ];
    
    var dynamic = [
        ['a0', 32.840801, -117.244842],
        ['a0zz', 32.840801, -117.244842]
    ];
    
    var found = markers.filter( m => dynamic.some( d => d[0] === m[0]) );
    
    
    console.log(found)

    【讨论】:

    • 好问题。我想你是对的。 some() 函数只会检查类似 d.indexOf(m[0]) &lt; -1 的内容
    • 我在 IDE 中收到 an expression is expected =&gt;,即使我尝试了代码并且它在控制台中运行。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多