【问题标题】:Use a 'Like' statement to find similar values in JSON data使用“Like”语句在 JSON 数据中查找相似值
【发布时间】:2019-08-07 00:36:24
【问题描述】:

我有一些 JSON 数据。我试图从中获得类似的值。有没有办法使用javascript来做到这一点?我正在从服务器获取我的 JSON。但我有一个样本。我正在尝试将不同的浏览器版本加载到他们的optgroups 中。

有没有办法做到这一点?

JSON:

[
{
    "browser": "Amazon Silk 3.30"
},
{
    "browser": "Amazon Silk 49.2"
},
{
    "browser": "Edge 42.11"
},
{
    "browser": "Edge 42.15"
},
{
    "browser": "Google Chrome 0.01"
},
{
    "browser": "Google Chrome 0.03"
}
]

HTML

<select id="browsers" style="max-height: 150px; overflow: auto;"></select>

JavaScript

$.getJSON(jsonBrowser, function(data) {
    data.forEach((d, i) => {
        let browser_val = d.browser.replace(/ /g, "%20");
        $('#browsers').append(`<option value=${browser_val} selected>${d.browser}</option>`);
    });
});
}

结果: 目前,此代码仅通过下拉列表填充。

 Amazon Silk 3.30
 Amazon Silk 49.2
 Edge 42.11
 Edge 42.15
 Google Chrome 0.01
 Google Chrome 0.03

我需要的结果:我想在我的下拉列表中使用optgroups 来显示:

**Amazon**:
 Amazon Silk 3.30
 Amazon Silk 49.2
**Edge**:
 Edge 42.11
 Edge 42.15
**Google**:
 Google Chrome 0.01
 Google Chrome 0.03

有没有办法使用 JavaScript/jQuery 对它们进行分组?

【问题讨论】:

  • 当然。你如何定义组名?第一个空格前的字符串?
  • @HereticMonkey 我正计划对它们进行硬编码。但理论上是的,它是第一个空格之前的字符串
  • "Like" 在这种情况下仅表示“共享相同的子字符串”,因此您可以获取browser_val.substring(0, browser_val.indexOf(' ')),如果不存在该名称的optgroup,则继续上。不过先对数组进行排序;见Sort array of objects by string property value

标签: javascript jquery json select optgroup


【解决方案1】:

json 排序是否正确?在您的代码的当前状态下,optgroups 只有在所有相似的浏览器相继出现时才有意义。但是如果你有边缘,然后是铬,然后又是边缘呢?在这种情况下,我会将其拆分为 2 个循环

1) 循环遍历 json 并根据名称将值推送到 new array

2) 循环遍历新数组并构建内容

var example = [
{
    "browser": "Amazon Silk 3.30"
},
{
    "browser": "Amazon Silk 49.2"
},
{
    "browser": "Edge 42.11"
},
{
    "browser": "Edge 42.15"
},
{
    "browser": "Google Chrome 0.01"
},
{
    "browser": "Google Chrome 0.03"
},
{
    "browser": "Edge 42.13"
},
{
    "browser": "Amazon Silk 50"
}
]

var grouped_browsers = {
    'Edge': [],
    'Amazon': [],
    'Chrome': []
};
$.each(example, function() {
    if (this.browser.indexOf('Edge') !== -1) {
        grouped_browsers['Edge'].push(this.browser);
    } else if (this.browser.indexOf('Amazon') !== -1) {
        grouped_browsers['Amazon'].push(this.browser);
    } else if (this.browser.indexOf('Chrome') !== -1) {
        grouped_browsers['Chrome'].push(this.browser);
    } else {
        grouped_browsers['Other'].push(this.browser);
    }
});

var rendered_groups = '';
var formatted_browsers = {
    'Amazon': 'Amazon Silk',
    'Chrome': 'Google Chrome',
    'Edge': 'Edge'
};
$.each(grouped_browsers, function(key, value) {
    rendered_groups += '<optgroup label="'+formatted_browsers[key]+'">';
    $.each(value, function() {
        rendered_groups += '<option value="'+this+'">'+this+'</option>';
    });
    rendered_groups += '</optgroup>';

});
$('#browsers').html(rendered_groups);

我做了一个简单的解决方案https://jsfiddle.net/rLbzs1ky/1/

【讨论】:

  • 我的代码可以双向工作。但它可以进行相当多的优化。考虑到您知道顺序,也许我稍后会添加一个不太复杂的版本
【解决方案2】:

您可以将Array.prototype.reduceString.prototype.split 结合使用来创建一种地图。像这样的:

const arr = [{
  "browser": "Amazon Silk 3.30"
}, {
  "browser": "Amazon Silk 49.2"
}, {
  "browser": "Edge 42.11"
}, {
  "browser": "Edge 42.15"
}, {
  "browser": "Google Chrome 0.01"
}, {
  "browser": "Google Chrome 0.03"
}];

const groupBrowser = (accum, el) => {
  const [groupName] = el.browser.split(' '); //Group by the first word in the string
  if (accum[groupName]) {
    accum[groupName].push(el.browser);
  } else {
    accum[groupName] = [el.browser];
  }
  return accum;
};

//Use the DOM API to create option elements for each group
const generateOptgroupEls = entry => {
  const [key, val] = entry;
  const optgroupEl = document.createElement('optgroup');
  optgroupEl.label = `**${key}**`;

  val.forEach(browser => {
    const optionEl = document.createElement('option');
    optionEl.value = browser;
    optionEl.text = browser;
    optgroupEl.appendChild(optionEl);
  });

  return optgroupEl;
};

//Create the select DOM el we will load up with options
const selectEl = document.createElement('select');

//Group the data
const groups = arr.reduce(groupBrowser, {});

//Create optgroup DOM elements based on group data
const optgroupEls = Object.entries(groups).map(generateOptgroupEls);

//Append the optgroups to the select el
optgroupEls.forEach(optgroupEl => {
  selectEl.appendChild(optgroupEl);
});

//Append the select el to the document
document.querySelector('#target').appendChild(selectEl);
&lt;div id="target"&gt;&lt;/div&gt;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-05-11
    • 1970-01-01
    • 1970-01-01
    • 2020-01-23
    • 2019-10-25
    • 2020-09-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多