Home > Blockchain >  How to match two values in a multi dimensional json
How to match two values in a multi dimensional json

Time:01-16

I am trying to match two values of the same object in a multidimensional JSON. First I search for a value in key4 for two input fields which is suggestion featured. After selecting 2 input fields and clicking submit button, I need to check that two input values present in the same set of JSON objects in multi-dimensional JSON (Check for key4 in each JSON object). I mean when searching for Test value 3 and Test value 5 in two input fields, I should get the first element of JSON in below in filter-records element, that is

{
  "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 >
    <input type="input"  id="txt-search" placeholder="Type your search character">
    <div id="match-list"></div>
    <input type="input"  id="txt-search2" placeholder="Type your search character">
    <div id="match-list2"></div>
    <input type="submit" id="submit" value="submit">
  </div>
</form>


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

In live mode I get JSON from file which I get with the following code const res2 = await fetch('./tt.json');const states2 = await res2.json();. With this code, I get the following error in the console. Uncaught TypeError: Cannot read properties of undefined (reading 'search') and Uncaught SyntaxError: Unexpected token ] in JSON at position 0. How to make it work for two values in a multi-dimension JSON?

CodePudding user response:

Create the functions so that the result of one search can be "fed" as the input (states) of the second search (so, actually, you perform the second search on a state already filtered by the first search). This is more efficient, and the code is much cleaner:

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 >
    <input type="input"  id="txt-search" placeholder="Type your search character" />
    <div id="match-list"></div>
    <input type="input"  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  style="overflow-x:auto;">
  <div >
    <div>
      <div id="filter-records"></div>
    </div>
  </div>
</div>

  •  Tags:  
  • Related