Nesne koruma anahtarlarının üzerine eşleme yapın


129

mapUndercore.js içindeki işlev, bir javascript nesnesiyle çağrılırsa, nesnenin değerlerinden eşlenen bir değerler dizisi döndürür.

_.map({one: 1, two: 2, three: 3}, function(num, key){ return num * 3; });
=> [3, 6, 9]

anahtarları korumasını sağlamanın bir yolu var mı? yani, dönen bir işlev istiyorum

{one: 3, two: 6, three: 9}

Siz de benim gibi buraya yeni bir nesne döndürmek yerine gerçek nesneyi değiştiren 'mapValues' benzeri bir işlev aramak için geldiyseniz, şu basit çözümü kontrol edin: stackoverflow.com/questions/30894044/…
Michael Trouw

Yanıtlar:


228

ile alt çizgi

Alt çizgi _.mapObject, değerleri eşlemek ve anahtarları korumak için bir işlev sağlar .

_.mapObject({ one: 1, two: 2, three: 3 }, function (v) { return v * 3; });

// => { one: 3, two: 6, three: 9 }

DEMO


ile Lodash

Lodash _.mapValues, değerleri eşlemek ve anahtarları korumak için bir işlev sağlar .

_.mapValues({ one: 1, two: 2, three: 3 }, function (v) { return v * 3; });

// => { one: 3, two: 6, three: 9 }

DEMO


Bir _.mapValues ​​işlevini alt çizgi haline getirme çabaları olmuştur: İlgili Sorun , _.mapValues ​​için Çekme İsteği . Umarım bu devam eder :)
çekiliş

bana bir nesneye bir NESNE yapıyormuşsunuz gibi görünüyor, yoksa aklımı mı kaçırdım?
jsh

Bu durumda @jsh, _.map()dönen [['one', 3], ['two', 6], ['three', 9]]diziler dizisi olan, ve _.object()bir nesne içine geri dönmektedir.
Jezen Thomas

56

Alt çizgiye benzer bir yardımcı program kitaplığı olan lodash'ta gerekli işlevi bulmayı başardım.

http://lodash.com/docs#mapValues

_.mapValues(object, [callback=identity], [thisArg])

Geri çağırma yoluyla nesnenin her kendi numaralandırılabilir özelliğini çalıştırarak oluşturulan nesne ve değerlerle aynı anahtarlara sahip bir nesne oluşturur. Geri arama thisArg'ye bağlıdır ve üç bağımsız değişkenle çağrılır; (değer, anahtar, nesne).


19

var mapped = _.reduce({ one: 1, two: 2, three: 3 }, function(obj, val, key) {
    obj[key] = val*3;
    return obj;
}, {});

console.log(mapped);
<script src="http://underscorejs.org/underscore-min.js"></script>
<script src="https://getfirebug.com/firebug-lite-debug.js"></script>


13

Bunun eski olduğunu biliyorum, ancak artık Underscore'un nesneler için yeni bir haritası var:

_.mapObject(object, iteratee, [context]) 

Elbette hem diziler hem de nesneler için esnek bir harita oluşturabilirsiniz.

_.fmap = function(arrayOrObject, fn, context){
    if(this.isArray(arrayOrObject))
      return _.map(arrayOrObject, fn, context);
    else
      return _.mapObject(arrayOrObject, fn, context);
}

5
Lodash kullanıcılarına not: jdalton, bu değişiklikle birlikte undercore.js ile uyumluluğu bozmaya karar verdi . lodash desteklemeyecek mapObject; mapValuesBunun yerine Lodash'ın yöntemine bakın .
Mark Amery

13

Bu sürüm düz JS ( ES6 / ES2015 ) nasıl olur?

let newObj = Object.assign(...Object.keys(obj).map(k => ({[k]: obj[k] * 3})));

jsbin

Bir nesneyi özyinelemeli olarak eşlemek istiyorsanız (iç içe geçmiş nesnelerle eşleme), şu şekilde yapılabilir:

const mapObjRecursive = (obj) => {
  Object.keys(obj).forEach(key => {
    if (typeof obj[key] === 'object') obj[key] = mapObjRecursive(obj[key]);
    else obj[key] = obj[key] * 3;
  });
  return obj;
};

jsbin

ES7 / ES2016'dan beri Object.entriesbunun yerine kullanabilirsiniz Object.keys:

let newObj = Object.assign(...Object.entries(obj).map([k, v] => ({[k]: v * 3})));

5

Uzun zaman geçtiğini biliyorum, ancak yine de katlama yoluyla en bariz çözüm (diğer adıyla js'de azaltma) eksik, bütünlük uğruna burada bırakacağım:

function mapO(f, o) {
  return Object.keys(o).reduce((acc, key) => {
    acc[key] = f(o[key])
    return acc
  }, {})
}

Lodash kütüphanesinin kullanımında sorun yok ama programcılar bu tür kütüphaneleri kullanıyor ve bu şeylerin vanilya JS'de nasıl başarılacağını bilmiyorlar. Bu yüzden cevabınızı takdir ediyorum!
cyonder

3

_.map bir Nesne değil, Dizi döndürür.

Bir nesne istiyorsanız, farklı bir işlevi kullanmanız daha iyi olur, örneğin each; Haritayı gerçekten kullanmak istiyorsanız, bunun gibi bir şey yapabilirsiniz:

Object.keys(object).map(function(value, index) {
   object[value] *= 3;
})

ama bu kafa karıştırıcıdır, eğer mapbir kişi sonuç olarak bir diziye sahip olmayı bekleyebilir ve sonra onunla bir şeyler yapabilir.


Bunu undercore.js'de denemenin doğal olmayacağına dair dokümanları okurken bir his duydum. Kullanım durumumun oldukça doğal olduğunu düşünüyorum, neden desteklemiyorlar?
xuanji

Bunun bir nedeni, mapbir dizi üreten bir girdiyi çıktı olarak değiştirmek için kullanılması olabilir, oluşturabilir _.objectve _.map@GG olarak kullanabilirsiniz. yazdı, ama bu noktada bu bir zevk meselesi.
Alberto Zaccagni

3

Sanırım bir mapValues işlevi istiyorsunuz (bir işlevi bir nesnenin değerleri üzerine eşlemek için), ki bu, kendiniz uygulamanız için yeterince kolay:

mapValues = function(obj, f) {
  var k, result, v;
  result = {};
  for (k in obj) {
    v = obj[k];
    result[k] = f(v);
  }
  return result;
};

2
const mapObject = (obj = {}, mapper) =>
  Object.entries(obj).reduce(
    (acc, [key, val]) => ({ ...acc, [key]: mapper(val) }),
    {},
  );

Bu yanıtı kendim eklemek üzereydim. Kaydırdığıma sevindim!
Bill Criswell

0

Alt çizgi harita hatası için bir karma düzeltme : P

_.mixin({ 
    mapobj : function( obj, iteratee, context ) {
        if (obj == null) return [];
        iteratee = _.iteratee(iteratee, context);
        var keys = obj.length !== +obj.length && _.keys(obj),
            length = (keys || obj).length,
            results = {},
            currentKey;
        for (var index = 0; index < length; index++) {
          currentKey = keys ? keys[index] : index;
          results[currentKey] = iteratee(obj[currentKey], currentKey, obj);
        }
        if ( _.isObject( obj ) ) {
            return _.object( results ) ;
        } 
        return results;
    }
}); 

Doğru anahtarı tutan ve nesne olarak geri dönen basit bir çözüm Hala i misafir olarak kullanılır, bu işlevi bugy _.map işlevini geçersiz kılmak için kullanabilirsiniz

ya da sadece benim karışımım olarak kullandığım gibi

_.mapobj ( options , function( val, key, list ) 

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.