【问题标题】:How to match two values in a multi dimensional json如何匹配多维json中的两个值
【发布时间】:2022-01-15 16:02:27
【问题描述】:

我正在尝试在多维 JSON 中匹配同一对象的两个值。首先,我在 key4 中为两个以建议为特色的输入字段搜索一个值。选择 2 个输入字段并单击提交按钮后,我需要检查两个输入值是否存在于多维 JSON 中的同一组 JSON 对象中(检查每个 JSON 对象中的 key4)。我的意思是在两个输入字段中搜索Test value 3Test value 5 时,我应该在filter-records 元素中得到JSON 的第一个元素,即

{
  "key1": "Test value 1",
  "key3" : [{
      "key4" : "Test value 3",
      "key5" : "Test value 4"
    },
    {
      "key4" : "Test value 5",
      "key5" : "Test value 6"
    }]
}

var object = [{
    "key1": "Test value 1",
    "key3": [{
        "key4": "Test value 3",
        "key5": "Test value 4"
      },
      {
        "key4": "Test value 5",
        "key5": "Test value 6"
      }
    ]
  },
  {
    "key1": "Test value 11",
    "key3": [{
        "key4": "Test value 13",
        "key5": "Test value 14"
      },
      {
        "key4": "Test value 15",
        "key5": "Test value 16"
      }
    ]
  }
];





const search = document.getElementById("txt-search");
const matchList = document.getElementById("match-list");

searchStates = async searchText => {
  const states = object;
  let matches = states.filter(state => {
    const regex = new RegExp(`^${searchText}`, 'gi');
    return state.key3.some(i => i.key4.match(regex)) //(regex);              
  });
  matchList.textContent = JSON.stringify(matches, null, 2)
};





search.addEventListener("keyup", () => searchStates(search.value));


const search2 = document.getElementById("txt-search2");
const matchList2 = document.getElementById("match-list2");

searchStates2 = async searchText2 => {
  const states2 = object;
  let matches2 = states2.filter(state2 => {
    const regex2 = new RegExp(`^${searchText2}`, 'gi');
    return state2.key3.some(i => i.key4.match(regex2)) //(regex);              
  });
  matchList2.textContent = JSON.stringify(matches2, null, 2)
};

search2.addEventListener("keyup", () => searchStates2(search2.value));

const search3 = document.getElementById("submit");
const matchList3 = document.getElementById("filter-records");
searchStates3 = async(searchText3, searchText4) => {
  const states3 = object;
  let matches3 = states3.filter(state3 => {

    return state3.key3.some(i => i.key4 == searchText3 && i.key4 == searchText4)
  });
  matchList3.textContent = JSON.stringify(matches3, null, 2)
};



search3.addEventListener("submit", (evt) => {
  evt.preventDefault();
  searchStates3(search.value, search2.value)
});
<form role="form">
  <div class="form-group">
    <input type="input" class="form-control" id="txt-search" placeholder="Type your search character">
    <div id="match-list"></div>
    <input type="input" class="form-control" id="txt-search2" placeholder="Type your search character">
    <div id="match-list2"></div>
    <input type="submit" id="submit" value="submit">
  </div>
</form>


<div class="row" style="overflow-x:auto;">
  <div class="col">
    <div>
      <div id="filter-records"></div>
    </div>
  </div>
</div>

在实时模式下,我从使用以下代码 const res2 = await fetch('./tt.json');const states2 = await res2.json(); 获得的文件中获取 JSON。使用此代码,我在控制台中收到以下错误。 Uncaught TypeError: Cannot read properties of undefined (reading 'search')Uncaught SyntaxError: Unexpected token ] in JSON at position 0。如何使其适用于多维 JSON 中的两个值?

【问题讨论】:

  • 请说明您的代码的目标。另外,请将您问题中的代码重点放在与手头问题相关的内容上。此数据是否具有已定义的形状或架构?您是在寻找响应数据中的值之间的完全匹配,还是一个字符串包含另一个字符串?
  • searchStates 和 searchStates2 是建议,因此没有完全匹配,但 searchStates3 完全匹配。

标签: javascript json


【解决方案1】:

创建函数,以便可以“输入”一次搜索的结果作为第二次搜索的输入(状态)(因此,实际上,您对已被第一次搜索过滤的状态执行第二次搜索)。这样效率更高,代码也更干净:

const object = [{
    "key1": "Test value 1",
    "key3": [{
        "key4": "Test value 3",
        "key5": "Test value 4"
      },
      {
        "key4": "Test value 5",
        "key5": "Test value 6"
      }
    ]
  },
  {
    "key1": "Test value 11",
    "key3": [{
        "key4": "Test value 13",
        "key5": "Test value 14"
      },
      {
        "key4": "Test value 15",
        "key5": "Test value 16"
      }
    ]
  }
];

const search = document.getElementById("txt-search");
const matchList = document.getElementById("match-list");
const search2 = document.getElementById("txt-search2");
const matchList2 = document.getElementById("match-list2");

const searchStates = ({ search, states }) => {
  const regex = new RegExp(`^${search}`, 'gi');
  return states.filter(state => state.key3.some(e => e.key4.match(regex)))
}

const updateElTextContent = ({ el, text }) => {
  el.textContent = JSON.stringify(text, null, 2)
}

const searchKeyupHandler = (matchListContainer, object) => (value) => {
  const matches = searchStates({ search: value, states: object })
  updateElTextContent({ el: matchListContainer, text: matches })
}

const input1Handler = searchKeyupHandler(matchList, object)
const input2Handler = searchKeyupHandler(matchList2, object)

search.addEventListener("keyup", (e) => {
  input1Handler(e.target.value)
});
search2.addEventListener("keyup", (e) => {
  input2Handler(e.target.value)
});


const form = document.getElementById('form')
const matchList3 = document.getElementById("filter-records");

// just feed the result of the first search match to the
// second one - as states
const searchTwoStates = ({ s1, s2, obj }) => {
  const match1 = searchStates({ search: s1, states: obj })
  const match2 = searchStates({ search: s2, states: match1 })
  updateElTextContent({ el: matchList3, text: match2 })
};

form.addEventListener("submit", (evt) => {
  evt.preventDefault();
  evt.stopPropagation();
  searchTwoStates({ s1: search.value, s2: search2.value, obj: object })
});
<form id="form" role="form">
  <div class="form-group">
    <input type="input" class="form-control" id="txt-search" placeholder="Type your search character" />
    <div id="match-list"></div>
    <input type="input" class="form-control" id="txt-search2" placeholder="Type your search character" />
    <div id="match-list2"></div>
    <input type="submit" id="submit" value="submit" />
    <input type="reset" value="reset" />
  </div>
</form>


<div class="row" style="overflow-x:auto;">
  <div class="col">
    <div>
      <div id="filter-records"></div>
    </div>
  </div>
</div>

【讨论】:

  • 嗨,作为旁注,我可以只返回唯一匹配的 key4 而不是来自 return states.filter(state =&gt; state.key3.some(e =&gt; e.key4.match(regex))) 的完整对象
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-08-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-03-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多