Поиск вложенного объекта через свойство для дочерних элементов уровня n [duplicate]

Простая форма загрузки

 <script>
   //form Submit
   $("form").submit(function(evt){	 
      evt.preventDefault();
      var formData = new FormData($(this)[0]);
   $.ajax({
       url: 'fileUpload',
       type: 'POST',
       data: formData,
       async: false,
       cache: false,
       contentType: false,
       enctype: 'multipart/form-data',
       processData: false,
       success: function (response) {
         alert(response);
       }
   });
   return false;
 });
</script>
<!--Upload Form-->
<form>
  <table>
    <tr>
      <td colspan="2">File Upload</td>
    </tr>
    <tr>
      <th>Select File </th>
      <td><input id="csv" name="csv" type="file" /></td>
    </tr>
    <tr>
      <td colspan="2">
        <input type="submit" value="submit"/> 
      </td>
    </tr>
  </table>
</form>

14
задан Alan 24 February 2012 в 01:14
поделиться

7 ответов

Что-то вроде этого должно работать:

var testObj = {
    test: 'testValue',
    test1: 'testValue1',
    test2: {
        test2a: 'testValue',
        test2b: 'testValue1'
    }
}

function searchObj (obj, query) {

    for (var key in obj) {
        var value = obj[key];

        if (typeof value === 'object') {
            searchObj(value, query);
        }

        if (value === query) {
            console.log('property=' + key + ' value=' + value);
        }

    }

}

Если вы выполните searchObj(testObj, 'testValue');, он будет записывать на консоль следующее:

property=test value=testValue
property=test2a value=testValue

Очевидно, вы можете заменить console.log с тем, что вы хотите, или добавьте параметр обратного вызова в функцию searchObj, чтобы сделать его более многоразовым.

EDIT: добавлен параметр query, который позволяет вам указать желаемое значение для поиска, когда вы вызываете функцию.

21
ответ дан Bryan Downing 22 August 2018 в 11:15
поделиться
  • 1
    +1, но для предотвращения поиска объектов в цепочке [[Prototype]] необходимо включить тест hasOwnProperty. Рассмотрите также тестирование для typeof obj[key] == 'function'. – RobG 24 February 2012 в 02:26

Вот мое решение, оно соответствует заданной строке / значению с помощью теста regex и возвращает сопоставленный массив. Это не рекурсивно, однако вы удалили это из своего вопроса.

Это из моего ответа в следующем потоке: Поиск объекта JavaScript

Те же принципы, что и другие, предлагаемые - поиск объекта для данного значения , для тех, кто ищет это решение.

Функция:

Array.prototype.findValue = function(name, value){
   var array = $.map(this, function(v,i){
        var haystack = v[name];
        var needle = new RegExp(value);
        // check for string in haystack
        // return the matched item if true, or null otherwise
      return needle.test(haystack) ? v : null;
   });
  return this;
}

Ваш объект:

myObject = {
        name : "soccer",
        elems : [
            {name : "FC Barcelona"},
            {name : "Liverpool FC"}
        ]
    },
    {
        name : "basketball",
        elems : [
            {name : "Dallas Mavericks"}
        ]
    }

Для использования:

(Это приведет к поиску вашего объекта myObject.

var matched = myObject.elems.findValue('name', 'FC');
console.log(matched);

Результат - проверьте консоль:

[Object, Object, keepMatching: function, findValue: function]
0: Object
name: "FC Barcelona"
__proto__: Object
1: Object
name: "Liverpool FC"
__proto__: Object
length: 2
__proto__: Array[0]

Если вы хотите получить точное совпадение, вы просто измените регулярное выражение в тройном выражении соответствует базовому значению. то есть

v[name] === value ? v : null 
2
ответ дан Community 22 August 2018 в 11:15
поделиться

Эта функция будет искать в объекте. Он будет соответствовать поисковому запросу с каждым свойством объекта. Это полезно, когда вам нужно искать в многомерном объекте. Проведя часы, я получил этот код из Google AngularJS Project.

/* Seach in Object */

var comparator = function(obj, text) {
if (obj && text && typeof obj === 'object' && typeof text === 'object') {
    for (var objKey in obj) {
        if (objKey.charAt(0) !== '$' && hasOwnProperty.call(obj, objKey) &&
                comparator(obj[objKey], text[objKey])) {
            return true;
        }
    }
    return false;
}
text = ('' + text).toLowerCase();
return ('' + obj).toLowerCase().indexOf(text) > -1;
};

var search = function(obj, text) {
if (typeof text == 'string' && text.charAt(0) === '!') {
    return !search(obj, text.substr(1));
}
switch (typeof obj) {
    case "boolean":
    case "number":
    case "string":
        return comparator(obj, text);
    case "object":
        switch (typeof text) {
            case "object":
                return comparator(obj, text);
            default:
                for (var objKey in obj) {
                    if (objKey.charAt(0) !== '$' && search(obj[objKey], text)) {
                        return true;
                    }
                }
                break;
        }
        return false;
    case "array":
        for (var i = 0; i < obj.length; i++) {
            if (search(obj[i], text)) {
                return true;
            }
        }
        return false;
    default:
        return false;
}
};
2
ответ дан Hardik Sondagar 22 August 2018 в 11:15
поделиться
  • 1
    Это, по-видимому, обрабатывает рекурсивные структуры, которых нет в принятом ответе. – Automatico 9 November 2017 в 22:27
//example from the Binance API.  
//They return a ticker object with ALL of their currency pairs 
//that contain the current price of each pair.  
//We want to allow users to enter in a currency pair, 
//and return the current ask price of the currency.  E.g.,
//users are asking for something that we do not know if it
// exists until the ticker object is returned.  Therefore, we 
//must search for a property in the object, if it exists, 
//return the value of the found property.  

let symbol = 'LTCBTC';
if (symbol in ticker) {
   console.log(ticker[symbol]);
} else {
console.log('symbol not found or not supported');
}
//This example uses the javascript property accessor to access 
//the property once we've verified it is in the 
//object [js property accessors][1] and the in 
//operator [js in property][2]
-1
ответ дан Jon Luzader 22 August 2018 в 11:15
поделиться

Я отредактировал ответ Брайана Даунинга, чтобы напечатать иерархию для глубоких объектов:

   function searchObj (obj, query, prefix /*not to be set*/) {
    prefix = prefix || "---";
    var printKey;

    for (var key in obj) {
        var value = obj[key];

        if (typeof value === 'object') {
            if (searchObj(value, query, prefix + "|---")) {
                console.log(prefix + ' ' + key);
                printKey = true;
            }
        }

        if (value === query) {
            console.log(prefix + ' ' + key + ' = ' + value);

            return true;
        }
    }

    return printKey;
}

Затем запустите searchObj(testObj, 'testValue');

0
ответ дан Psddp 22 August 2018 в 11:15
поделиться

Вот некоторые современные решения этого старого вопроса. Вы можете расширить его в соответствии с вашими потребностями. Предположим, что следующая структура данных:

table = {
  row1: {
    col1: 'A',
    col2: 'B',
    col3: 'C'
  },
  row2: {
    col1: 'D',
    col2: 'A',
    col3: 'F'
  },
  row3: {
    col1: 'E',
    col2: 'G',
    col3: 'C'
  }
};

Чтобы получить массив ключей к объектам, где свойство col3 равно «C»:

Object.keys(table).filter(function(row) {
  return table[row].col3==='C';
});

Это вернет ['row1', 'row3'].

Чтобы получить новый объект строк, где свойство col3 равно «C»:

Object.keys(table).reduce(function(accumulator, currentValue) {
  if (table[currentValue].col3==='C') accumulator[currentValue] = table[currentValue];
  return accumulator;
}, {});

Это вернет

{
  row1: {
    col1: 'A',
    col2: 'B',
    col3: 'C'
  },
  row3: {
    col1: 'E',
    col2: 'G',
    col3: 'C'
  }
}

Обратите внимание, что приведенные выше ответы получены из аналогичного вопроса .

0
ответ дан thdoan 22 August 2018 в 11:15
поделиться

Вот более удобный статический статический метод, основанный на подходе Брайана:

/**
* Find properties matching the value down the object tree-structure.
* Ignores prototype structure and escapes endless cyclic nesting of
* objects in one another.
*
* @param {Object} object Object possibly containing the value.
* @param {String} value Value to search for.
* @returns {Array<String>} Property paths where the value is found. 
*/
getPropertyByValue: function (object, value) {
  var valuePaths;
  var visitedObjects = [];

  function collectValuePaths(object, value, path, matchings) {

    for (var property in object) {

      if (
        visitedObjects.indexOf(object) < 0 &&
        typeof object[property] === 'object') {

        // Down one level:

        visitedObjects.push(
          object);

        path =
          path +
          property + ".";

        collectValuePaths(
          object[property],
          value,
          path,
          matchings);
      }

      if (object[property] === value) {

        // Matching found:

        matchings.push(
          path +
          property);
      }

      path = "";
    }

    return matchings;
  }

  valuePaths =
    collectValuePaths(
      object,
      value,
      "",
      []);

   return valuePaths;
}

Для объекта

var testObj = {
  test: 'testValue',
  test1: 'testValue1',
  test2: {
      test2a: 'testValue',
      test2b: 'testValue1'
  }
}

приведет к

["test", "test2.test2a"]
1
ответ дан Zon 22 August 2018 в 11:15
поделиться
Другие вопросы по тегам:

Похожие вопросы: