3

I got an array list like the data below. I want make a function, input a number like '203', then the function will return 2 value "John" & "d", but I don't know how to make it.

There is a return value when I key in console.log(data.i) in the browser developer tool console, but it showed nothing in real code execution.

var data = {
  "John": {
    "a": "200",
    "b": "201",
    "c": "202",
    "d": "203",
    "e": "204",
    "f": "205"
  },
  "Allen": {
    "y": "100",
    "z": "103"
  }
}
for (i in data) {
  console.log(i); // return John, Allen...
  for (var j in data.i) {
    console.log(j[0]); //return nothing
  }
}
Eddie
  • 26,593
  • 6
  • 36
  • 58
user3160227
  • 105
  • 2
  • 10
  • 1
    I think it is not duplicate because @user3160227 wants `John` and `d` to be returned when input is `203`... – vaku May 25 '19 at 04:56

3 Answers3

2

You need to use bracket notation like data[i]. Read more about Property Accessors

var data={
"John":{"a":"200","b":"201","c":"202","d":"203","e":"204","f":"205"},
"Allen":{"y":"100","z":"103"}
};

var input = "203";

function findVal(obj, val) {
  var result;
  for (var i in obj) {
    for (var j in data[i]) {
      if(data[i][j] === val) {
        result = {"key1" : i, "key2" : j};
      }
    }
  }
  return result;
}

console.log(findVal(data, input));
Nikhil Aggarwal
  • 28,197
  • 4
  • 43
  • 59
  • You answer doesn't tell about _"I want make a function, input a number like '203', then the function will return 2 value "John" & "d", but I don't know how to make it"_. Secondly if you thought only `data[i]` was the problem so you should have closed the question as duplicate. This question is asked almost every day so it doesn't mean we will answer it each and every time. – Maheer Ali May 25 '19 at 05:11
1

Inside each nested loop you can compare the element at that key to the given input and then log the key

var data = { "John": { "a": "200", "b": "201", "c": "202", "d": "203", "e": "204", "f": "205" }, "Allen": { "y": "100", "z": "103" } }
let input = "203"

for (i in data) {
  for (var j in data[i]) {
    if(data[i][j] === input) console.log(j)
  }
}

The way I would prefer is to use make a array of arrays of key value and then use find on that array.

var data = { "John": { "a": "200", "b": "201", "c": "202", "d": "203", "e": "204", "f": "205" }, "Allen": { "y": "100", "z": "103" } }
let input = "203"

let res = (Object.values(data)
               .flatMap(Object.entries)
               .find(([_,v]) => v === input) || {}
          )[0];
console.log(res)
Maheer Ali
  • 35,834
  • 5
  • 42
  • 73
1

This is probably an overkill in this situation but just in case you would need to go deeper than the 2 levels you currently have in the future.

This approach uses recursion to collect all the hits found and returns an array (or in this case I joined all to give you a string). It supports multiple hits as well:

var data = {
  "John": {
    "a": "200",
    "d": "203",
    "aa": {
      "z": "443",     // 3rd level
      "aaa": {
        "y": "331",   // 4th level etc...
        "z": "443"
      }
    }
  },
  "Allen": {
    "z": "103"
  }
}

const search = (obj, text) => {
  let hits = []
  const flatSearch = (obj, text = '', hits = [], path = null) =>
    Object.entries(obj).forEach(([key, value]) => {
      if (typeof value == 'object')
        flatSearch(value, text, hits, path ? `${path}.${key}` : key)
      else
        if (value.toString().toLowerCase().includes(text.toLowerCase()))
          hits.push([...path.split('.'), key])
    })
  flatSearch(obj, text, hits)
  return hits.map(x => x.join(' & ')).join(', ')  // Format the final output
}

console.log(search(data, '203'))  // Single hit
console.log(search(data, '331'))  // Single hit
console.log(search(data, '443'))  // Multi hit
Akrion
  • 18,117
  • 1
  • 34
  • 54