像XML一样简单地过滤JSON数组

nvbavucw  于 2023-08-08  发布在  其他
关注(0)|答案(3)|浏览(109)

在我的项目中,我正在从XML格式转向JSON格式。我有一个XML,它由这样的节点组成:

<Creature>
    <Name>Someone</Name>
    <Desert>false</Desert>
    <Woods>false</Woods>
    <Mountains>false</Mountains>
    <Swamp>false</Swamp>
</Creature>

字符串
和值等于标记名称的单选列表。就像这样:

<input type="radio" name="creature_terrain" value="Desert" />Desert<br>


旧代码通过执行以下操作过滤XML列表:

let selector = 'Creature > ' + selectedTerrain + ':contains("true")';
var filteredCreatures = $(creaturesArray).find(selector).parent();


现在我有了JSON数组:

{
    "Name": "Someone",
    "Desert": false,
    "Woods": false,
    "Mountains": false,
    "Swamp": false
  }


但是我找不到一种像XML那样优雅地过滤它的方法。我看到的唯一方法是切换/case。有什么建议吗?

bmp9r5qi

bmp9r5qi1#

如果它实际上是一个数组,你可以使用filter来查找匹配的地形是否为true。

编辑:你可以省略== true,因为它会将其评估为布尔值,但我更喜欢它,因为它更容易阅读和理解。

const creatures = [
  {
    "Name": "None",
    "Desert": false,
    "Woods": false,
    "Mountains": false,
    "Swamp": false
  },
  {
    "Name": "Swamp",
    "Desert": false,
    "Woods": false,
    "Mountains": false,
    "Swamp": true
  }
]

const terrain = "Swamp";

const creature = creatures.filter((e) => e[terrain] == true)

console.log(creature)

字符串

aor9mmx1

aor9mmx12#

假设你有一个 array 的对象而不是一个对象,你可以使用filter过滤掉那些符合特定条件的对象。
让我们扩展您的示例。
1.有两个对象(我已经降低了键名)。一个匹配“沙漠”另一个“沼泽”。有相应的无线电输入用于演示。
1.我在fieldset元素上附加了一个事件侦听器,以捕获其子元素(event delegation)的事件。
1.当一个更改事件被激发时,处理程序首先检查触发事件的元素是否是一个单选按钮。然后它将filters中的对象输出到一个新的数组中,该数组匹配“此对象的值是否为true”键?”的条件。我们使用更改后的单选按钮的value作为要检查的对象键。
1.为了方便起见,此对象的过滤数组显示在输出元素中。

const data=[{name:"Someone",desert:false,woods:false,mountains:false,swamp:true},{name:"Someone 2",desert:true,woods:false,mountains:false,swamp:false}];

// Get the terrain and output elements
const terrain = document.querySelector('.terrain');
const output = document.querySelector('.output');

// Add a listener to the terrain (fieldset) element
terrain.addEventListener('change', handleInput);

// When the terrain element catches an event
function handleInput(e) {

  // It checks to see if its a corresponding
  // creature_terrain radio button
  if (e.target.matches('[name="creature_terrain"]')) {
    
    // Assigns the changed radio input's value to `key`
    const key = e.target.value;

    // And uses that key in the condition to filter
    // those objects where there is a match
    const filtered = data.filter(obj => obj[key]);

    // If there are objects in the filtered array
    // show them in the output element
    if (filtered.length) {
      output.textContent = JSON.stringify(filtered, null, 2);
    } else {
      output.textContent = '';
    }
  }
}
code { display: block; margin-top: 1rem; }
<fieldset class="terrain">
  <legend>Terrain</legend>
  <input type="radio" name="creature_terrain" value="desert" />Desert
  <input type="radio" name="creature_terrain" value="swamp" />Swamp
</fieldset>
<pre><code class="output"></code></pre>
dldeef67

dldeef673#

尝试JavaScript原生数组方法,如findfilter

const filteredCreatures = creaturesArray.filter(creature => creature.Desert);

字符串

相关问题