Получить значения по имени свойства из объекта на разных уровнях

У меня есть объект в следующем формате, и мне нужно получить все значения из свойства Price на всех уровнях объекта.

var o = {
    Id: 1,
    Price: 10,
    Attribute: {
        Id: 1,
        Price: 2,
        Modifier: {
            Id: 34,
            Price: 33
        }
    }
};

Я думал о методах LinqToJS и jquery.map(), но я хотел бы получить метод как можно более универсальным. Я пробовал это, но это работает только на первом уровне:

var keys = $.map(o, function(value, key) {
    if (key == "Price") {
        return value;
    }
});
7 голосов | спросил Diego Fuks 19 MarpmSat, 19 Mar 2016 23:14:22 +03002016-03-19T23:14:22+03:0011 2016, 23:14:22

3 ответа


0

Вы можете использовать рекурсивную функцию, которая проверяет тип имени свойства и его тип. Если это имя Price, добавьте его в массив. Если это объект, пролистайте этот объект, чтобы найти ключ Price. Попробуйте это:

function getPrices(obj, arr) {
    $.each(obj, function(k, v) {
        if (k == "Price")
            arr.push(v);
        else if (typeof(v) == 'object')
            getPrices(obj[k], arr);
    });
    return arr;
}

var prices = getPrices(o, []);
console.log(prices); // = [10, 2, 33]

Рабочий пример

ответил Rory McCrossan 19 MarpmSat, 19 Mar 2016 23:20:41 +03002016-03-19T23:20:41+03:0011 2016, 23:20:41
0

Вы можете использовать $.map() в jQuery, чтобы сделать это очень легко:

 var o = {
  Id: 1,
  Price: 10,
  Attribute: {
    Id: 1,
    Price: 2,
    Modifier: {
      Id: 34,
      Price: 33
    }
  }
};


var res = $.map(o, function mapper(obj, key) {
  return key === "Price" ? obj : $.map(obj, mapper)
});


document.querySelector("pre").textContent = JSON.stringify(res)
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<pre></pre>

Это работает из-за нечетной функции, которую jQuery имеет $.map, где, если вы возвращаете массив из обратного вызова, он сливается с результатом .

Поэтому мы можем рекурсивно вызывать $.map с той же функцией для всего, что не является Price, и возвращаемый массив просто будет очищен до конечного результата.

Вы можете избежать некоторых звонков, если отметите typeof obj === "object", если хотите.

ответил Rory McCrossan 19 MarpmSat, 19 Mar 2016 23:20:41 +03002016-03-19T23:20:41+03:0011 2016, 23:20:41
0

Вы можете использовать цикл for..in, рекурсия

 var o = {
    Id: 1,
    Price: 10,
    Attribute: {
        Id: 1,
        Price: 2,
        Modifier: {
            Id: 34,
            Price: 33
        }
    }
};

var res = [];

(function re(obj) {
for (var prop in obj) {
  if (prop === "Price") {
    res.push(obj[prop])
  } else {
    re(obj[prop])
  }
}
}(o));

console.log(res)
ответил guest271314 19 MarpmSat, 19 Mar 2016 23:47:48 +03002016-03-19T23:47:48+03:0011 2016, 23:47:48

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

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132