javascript - রহম - জাভাস্ক্রিপ্ট লুপ




কিভাবে আমি জাভাস্ক্রিপ্ট বস্তুর গতিশীলভাবে একত্রিত করতে পারি? (20)

আমি রানটাইম এ দুটি (খুব সহজ) জাভাস্ক্রিপ্ট বস্তু একত্রিত করতে সক্ষম হতে হবে। উদাহরণস্বরূপ আমি চাই:

var obj1 = { food: 'pizza', car: 'ford' }
var obj2 = { animal: 'dog' }

obj1.merge(obj2);

//obj1 now has three properties: food, car, and animal

যে কেউ এই জন্য একটি স্ক্রিপ্ট আছে বা এই কাজ করতে নির্মিত একটি উপায় আছে? আমি recursion প্রয়োজন হয় না, এবং আমি ফাংশন মার্জ করার প্রয়োজন হয় না, ফ্ল্যাট বস্তু শুধুমাত্র পদ্ধতি।


কোড এক লাইন এন এন বস্তুর বৈশিষ্ট্য মার্জ করুন

একটি Object.assign পদ্ধতি ECMAScript 2015 (ES6) মানদন্ডের অংশ এবং আপনার যা দরকার তা ঠিক করে। ( IE সমর্থিত নয়)

var clone = Object.assign({}, obj);

Object.assign () পদ্ধতিটি এক বা একাধিক উত্স বস্তু থেকে লক্ষ্যবস্তু বস্তুর সমস্ত সংখ্যাসূচক নিজের বৈশিষ্ট্যগুলির মানগুলি অনুলিপি করার জন্য ব্যবহৃত হয়।

আরও পড়ুন ...

পুরানো ব্রাউজার সমর্থন করার জন্য পলিফিল :

if (!Object.assign) {
  Object.defineProperty(Object, 'assign', {
    enumerable: false,
    configurable: true,
    writable: true,
    value: function(target) {
      'use strict';
      if (target === undefined || target === null) {
        throw new TypeError('Cannot convert first argument to object');
      }

      var to = Object(target);
      for (var i = 1; i < arguments.length; i++) {
        var nextSource = arguments[i];
        if (nextSource === undefined || nextSource === null) {
          continue;
        }
        nextSource = Object(nextSource);

        var keysArray = Object.keys(nextSource);
        for (var nextIndex = 0, len = keysArray.length; nextIndex < len; nextIndex++) {
          var nextKey = keysArray[nextIndex];
          var desc = Object.getOwnPropertyDescriptor(nextSource, nextKey);
          if (desc !== undefined && desc.enumerable) {
            to[nextKey] = nextSource[nextKey];
          }
        }
      }
      return to;
    }
  });
}

JQuery এর মতোই প্রসারিত (), আপনার AngularJS এ একই ফাংশন রয়েছে:

// Merge the 'options' object into the 'settings' object
var settings = {validate: false, limit: 5, name: "foo"};
var options  = {validate: true, name: "bar"};
angular.extend(settings, options);

আপনি অবজেক্ট স্প্রেড বৈশিষ্ট্যগুলি ব্যবহার করতে পারেন - বর্তমানে একটি পর্যায় 3 ইসিএমএসস্ক্রিপ্ট প্রস্তাব।

const obj1 = { food: 'pizza', car: 'ford' };
const obj2 = { animal: 'dog' };

const obj3 = { ...obj1, ...obj2 };
console.log(obj3);


আপনি কেবল jQuery extend ব্যবহার করতে পারেন

var obj1 = { val1: false, limit: 5, name: "foo" };
var obj2 = { val2: true, name: "bar" };

jQuery.extend(obj1, obj2);

এখন obj1 obj1 এবং obj2 সকল মান রয়েছে


আমি বস্তুর বৈশিষ্ট্য একত্রিত কোড এখানে googled এবং শেষ পর্যন্ত। তবে যেহেতু recursive merge এর জন্য কোনও কোড ছিল না তাই আমি এটি লিখেছিলাম। (হয়তো jQuery প্রসারিত BTW recursive হয়?) যাইহোক, আশা করি অন্য কেউ এটি দরকারী হিসাবে ভাল পাবেন।

(এখন কোডটি Object.prototype ব্যবহার করে না :)

কোড

/*
* Recursively merge properties of two objects 
*/
function MergeRecursive(obj1, obj2) {

  for (var p in obj2) {
    try {
      // Property in destination object set; update its value.
      if ( obj2[p].constructor==Object ) {
        obj1[p] = MergeRecursive(obj1[p], obj2[p]);

      } else {
        obj1[p] = obj2[p];

      }

    } catch(e) {
      // Property in destination object not set; create it and set its value.
      obj1[p] = obj2[p];

    }
  }

  return obj1;
}

একটি উদাহরণ

o1 = {  a : 1,
        b : 2,
        c : {
          ca : 1,
          cb : 2,
          cc : {
            cca : 100,
            ccb : 200 } } };

o2 = {  a : 10,
        c : {
          ca : 10,
          cb : 20, 
          cc : {
            cca : 101,
            ccb : 202 } } };

o3 = MergeRecursive(o1, o2);

মত বস্তু o3 উত্পাদন করে

o3 = {  a : 10,
        b : 2,
        c : {
          ca : 10,
          cb : 20,
          cc : { 
            cca : 101,
            ccb : 202 } } };

উল্লেখ্য যে underscore.js এর underscorejs.org/#extend এক-লাইনারে এটি করে:

_.extend({name : 'moe'}, {age : 50});
=> {name : 'moe', age : 50}

এটি করার জন্য আপনার জন্য সর্বোত্তম উপায় হল একটি যথাযথ সম্পত্তি যোগ করা যা বস্তু। ডিফাইন প্রোপার্টি ব্যবহার করে অ-সংখ্যাসূচক।

আপনি যদি Object.prototype.extend এর সাথে সম্পত্তি তৈরি করতে চান তবে আপনি নতুন উপাদানের "প্রসারিত" না করেই আপনার অবজেক্টের বৈশিষ্ট্যগুলি পুনঃস্থাপন করতে সক্ষম হবেন।

আশা করি এই সাহায্য করে:

Object.defineProperty(Object.prototype, "extend", {
    enumerable: false,
    value: function(from) {
        var props = Object.getOwnPropertyNames(from);
        var dest = this;
        props.forEach(function(name) {
            if (name in dest) {
                var destination = Object.getOwnPropertyDescriptor(from, name);
                Object.defineProperty(dest, name, destination);
            }
        });
        return this;
    }
});

একবার আপনি যে কাজ আছে, আপনি করতে পারেন:

var obj = {
    name: 'stack',
    finish: 'overflow'
}
var replacement = {
    name: 'stock'
};

obj.extend(replacement);

আমি এখানে এটি সম্পর্কে একটি ব্লগ পোস্ট লিখেছিলাম: http://onemoredigit.com/post/1527191998/extending-objects-in-node-js


খুব বেশি জটিল বস্তুর জন্য আপনি JSON ব্যবহার করতে পারেন:

var obj1 = { food: 'pizza', car: 'ford' }
var obj2 = { animal: 'dog', car: 'chevy'}
var objMerge;

objMerge = JSON.stringify(obj1) + JSON.stringify(obj2);

// {"food": "pizza","car":"ford"}{"animal":"dog","car":"chevy"}

objMerge = objMerge.replace(/\}\{/, ","); //  \_ replace with comma for valid JSON

objMerge = JSON.parse(objMerge); // { food: 'pizza', animal: 'dog', car: 'chevy'}
// Of same keys in both objects, the last object's value is retained_/

এই উদাহরণে আপনি মনে করেন "} {" একটি স্ট্রিং এর মধ্যে ঘটবে না !


প্রদত্ত সমাধানগুলির আগে for..in loops in source.hasOwnProperty(property) চেক করার জন্য সংশোধন করা উচিত - অন্যথা, আপনি সম্পূর্ণ প্রোটোটাইপ শৃঙ্খলের বৈশিষ্ট্যগুলির অনুলিপি শেষ করতে পারেন যা খুব কমই পছন্দসই ...


যে কেউ গুগল ক্লোজার লাইব্রেরি ব্যবহার করা হয়:

goog.require('goog.object');
var a = {'a': 1, 'b': 2};
var b = {'b': 3, 'c': 4};
goog.object.extend(a, b);
// Now object a == {'a': 1, 'b': 3, 'c': 4};

অ্যারের জন্য অনুরূপ সহায়ক ফাংশন বিদ্যমান :

var a = [1, 2];
var b = [3, 4];
goog.array.extend(a, b); // Extends array 'a'
goog.array.concat(a, b); // Returns concatenation of array 'a' and 'b'

GitHub deepmerge নামে একটি লাইব্রেরি আছে: এটি কিছু ট্র্যাকশন পেয়ে মনে হচ্ছে। এটি একটি স্বতন্ত্র, npm এবং bower প্যাকেজ পরিচালকদের উভয় মাধ্যমে উপলব্ধ।

আমি উত্তর থেকে কপি-পাসিং কোড পরিবর্তে এই ব্যবহার বা উন্নতি করতে হবে।


Prototype এই আছে:

Object.extend = function(destination,source) {
    for (var property in source)
        destination[property] = source[property];
    return destination;
}

obj1.extend(obj2) আপনি চান কি করতে হবে।


ECMAScript 2018 স্ট্যান্ডার্ড পদ্ধতি

আপনি বস্তুর বিস্তার ব্যবহার করবে:

let merged = {...obj1, ...obj2};

/** There's no limit to the number of objects you can merge.
 *  Later properties overwrite earlier properties with the same name. */
const allRules = {...obj1, ...obj2, ...obj3};

ECMAScript 2015 (ES6) স্ট্যান্ডার্ড পদ্ধতি

/* For the case in question, you would do: */
Object.assign(obj1, obj2);

/** There's no limit to the number of objects you can merge.
 *  All objects get merged into the first object. 
 *  Only the object in the first argument is mutated and returned.
 *  Later properties overwrite earlier properties with the same name. */
const allRules = Object.assign({}, obj1, obj2, obj3, etc);

( এমডিএন জাভাস্ক্রিপ্ট রেফারেন্স দেখুন )

ES5 এবং এর আগে পদ্ধতি

for (var attrname in obj2) { obj1[attrname] = obj2[attrname]; }

মনে রাখবেন যে এটি কেবল obj2 সমস্ত গুণাবলী যুক্ত করবে যা আপনি এখনও obj1 ব্যবহার করতে চাইলে আপনি যা চান তা নাও হতে পারে।

আপনি যদি আপনার প্রোটোটাইপগুলির উপর ক্রপ করে এমন একটি ফ্রেমওয়ার্ক ব্যবহার করেন তবে hasOwnProperty মতো চেকগুলির সাথে ফ্যান্সিয়ার পেতে হবে, তবে এটি কোড 99% ক্ষেত্রে কাজ করবে।

উদাহরণ ফাংশন:

/**
 * Overwrites obj1's values with obj2's and adds obj2's if non existent in obj1
 * @param obj1
 * @param obj2
 * @returns obj3 a new object based on obj1 and obj2
 */
function merge_options(obj1,obj2){
    var obj3 = {};
    for (var attrname in obj1) { obj3[attrname] = obj1[attrname]; }
    for (var attrname in obj2) { obj3[attrname] = obj2[attrname]; }
    return obj3;
}

Object.assign ()

ECMAScript 2015 (ES6)

এটি একটি নতুন প্রযুক্তি, ECMAScript 2015 (ES6) মানের অংশ। এই প্রযুক্তির স্পেসিফিকেশনটি চূড়ান্ত করা হয়েছে, তবে বিভিন্ন ব্রাউজারগুলিতে ব্যবহারের এবং বাস্তবায়ন অবস্থার জন্য উপযুক্ততা টেবিলটি পরীক্ষা করুন।

Object.assign () পদ্ধতিটি এক বা একাধিক উত্স বস্তু থেকে লক্ষ্যবস্তু বস্তুর সমস্ত সংখ্যাসূচক নিজের বৈশিষ্ট্যগুলির মানগুলি অনুলিপি করার জন্য ব্যবহৃত হয়। এটা লক্ষ্য বস্তু ফিরে আসবে।

var o1 = { a: 1 };
var o2 = { b: 2 };
var o3 = { c: 3 };

var obj = Object.assign(o1, o2, o3);
console.log(obj); // { a: 1, b: 2, c: 3 }
console.log(o1);  // { a: 1, b: 2, c: 3 }, target object itself is changed.

আমি ডেভিড কোলিয়েরের পদ্ধতিটি প্রসারিত করেছি:

  • একাধিক বস্তু মার্জ সম্ভাবনা যোগ করা হয়েছে
  • গভীর বস্তু সমর্থন করে
  • ওভাররাইড প্যারামিটার (যা শেষ পরামিতি একটি বুলিয়ান সনাক্ত করা হয়)

যদি ওভাররাইড মিথ্যা হয় তবে কোনও সম্পত্তি ওভাররাইড করা হবে না তবে নতুন বৈশিষ্ট্য যোগ করা হবে।

ব্যবহার: obj.merge (মার্জ ... [, ওভাররাইড]);

এখানে আমার কোড:

Object.defineProperty(Object.prototype, "merge", {
    enumerable: false,
    value: function () {
        var override = true,
            dest = this,
            len = arguments.length,
            props, merge, i, from;

        if (typeof(arguments[arguments.length - 1]) === "boolean") {
            override = arguments[arguments.length - 1];
            len = arguments.length - 1;
        }

        for (i = 0; i < len; i++) {
            from = arguments[i];
            if (from != null) {
                Object.getOwnPropertyNames(from).forEach(function (name) {
                    var descriptor;

                    // nesting
                    if ((typeof(dest[name]) === "object" || typeof(dest[name]) === "undefined")
                            && typeof(from[name]) === "object") {

                        // ensure proper types (Array rsp Object)
                        if (typeof(dest[name]) === "undefined") {
                            dest[name] = Array.isArray(from[name]) ? [] : {};
                        }
                        if (override) {
                            if (!Array.isArray(dest[name]) && Array.isArray(from[name])) {
                                dest[name] = [];
                            }
                            else if (Array.isArray(dest[name]) && !Array.isArray(from[name])) {
                                dest[name] = {};
                            }
                        }
                        dest[name].merge(from[name], override);
                    } 

                    // flat properties
                    else if ((name in dest && override) || !(name in dest)) {
                        descriptor = Object.getOwnPropertyDescriptor(from, name);
                        if (descriptor.configurable) {
                            Object.defineProperty(dest, name, descriptor);
                        }
                    }
                });
            }
        }
        return this;
    }
});

উদাহরণ এবং টেস্টসেস:

function clone (obj) {
    return JSON.parse(JSON.stringify(obj));
}
var obj = {
    name : "trick",
    value : "value"
};

var mergeObj = {
    name : "truck",
    value2 : "value2"
};

var mergeObj2 = {
    name : "track",
    value : "mergeObj2",
    value2 : "value2-mergeObj2",
    value3 : "value3"
};

assertTrue("Standard", clone(obj).merge(mergeObj).equals({
    name : "truck",
    value : "value",
    value2 : "value2"
}));

assertTrue("Standard no Override", clone(obj).merge(mergeObj, false).equals({
    name : "trick",
    value : "value",
    value2 : "value2"
}));

assertTrue("Multiple", clone(obj).merge(mergeObj, mergeObj2).equals({
    name : "track",
    value : "mergeObj2",
    value2 : "value2-mergeObj2",
    value3 : "value3"
}));

assertTrue("Multiple no Override", clone(obj).merge(mergeObj, mergeObj2, false).equals({
    name : "trick",
    value : "value",
    value2 : "value2",
    value3 : "value3"
}));

var deep = {
    first : {
        name : "trick",
        val : "value"
    },
    second : {
        foo : "bar"
    }
};

var deepMerge = {
    first : {
        name : "track",
        anotherVal : "wohoo"
    },
    second : {
        foo : "baz",
        bar : "bam"
    },
    v : "on first layer"
};

assertTrue("Deep merges", clone(deep).merge(deepMerge).equals({
    first : {
        name : "track",
        val : "value",
        anotherVal : "wohoo"
    },
    second : {
        foo : "baz",
        bar : "bam"
    },
    v : "on first layer"
}));

assertTrue("Deep merges no override", clone(deep).merge(deepMerge, false).equals({
    first : {
        name : "trick",
        val : "value",
        anotherVal : "wohoo"
    },
    second : {
        foo : "bar",
        bar : "bam"
    },
    v : "on first layer"
}));

var obj1 = {a: 1, b: "hello"};
obj1.merge({c: 3});
assertTrue(obj1.equals({a: 1, b: "hello", c: 3}));

obj1.merge({a: 2, b: "mom", d: "new property"}, false);
assertTrue(obj1.equals({a: 1, b: "hello", c: 3, d: "new property"}));

var obj2 = {};
obj2.merge({a: 1}, {b: 2}, {a: 3});
assertTrue(obj2.equals({a: 3, b: 2}));

var a = [];
var b = [1, [2, 3], 4];
a.merge(b);
assertEquals(1, a[0]);
assertEquals([2, 3], a[1]);
assertEquals(4, a[2]);


var o1 = {};
var o2 = {a: 1, b: {c: 2}};
var o3 = {d: 3};
o1.merge(o2, o3);
assertTrue(o1.equals({a: 1, b: {c: 2}, d: 3}));
o1.b.c = 99;
assertTrue(o2.equals({a: 1, b: {c: 2}}));

// checking types with arrays and objects
var bo;
a = [];
bo = [1, {0:2, 1:3}, 4];
b = [1, [2, 3], 4];

a.merge(b);
assertTrue("Array stays Array?", Array.isArray(a[1]));

a = [];
a.merge(bo);
assertTrue("Object stays Object?", !Array.isArray(a[1]));

a = [];
a.merge(b);
a.merge(bo);
assertTrue("Object overrides Array", !Array.isArray(a[1]));

a = [];
a.merge(b);
a.merge(bo, false);
assertTrue("Object does not override Array", Array.isArray(a[1]));

a = [];
a.merge(bo);
a.merge(b);
assertTrue("Array overrides Object", Array.isArray(a[1]));

a = [];
a.merge(bo);
a.merge(b, false);
assertTrue("Array does not override Object", !Array.isArray(a[1]));

আমার সমান পদ্ধতি এখানে পাওয়া যাবে: জাভাস্ক্রিপ্ট বস্তুর তুলনা


Markus' এবং বনাম' উত্তর এর উপর ভিত্তি করে , এটি একটি বর্ধিত সংস্করণ। ফাংশন কোনো আর্গুমেন্ট নেয়। এটি DOM নোডগুলিতে বৈশিষ্ট্যগুলি সেট করতে এবং মানগুলির গভীর কপিগুলি তৈরি করতে ব্যবহার করা যেতে পারে । যাইহোক, প্রথম যুক্তি রেফারেন্স দ্বারা দেওয়া হয়।

একটি DOM নোড সনাক্ত করার জন্য, isDOMNode () ফাংশনটি ব্যবহার করা হয় (স্ট্যাক ওভারফ্লো প্রশ্ন জাভাস্ক্রিপ্ট ISDOM দেখুন - জাভাস্ক্রিপ্ট অবজেক্ট একটি DOM অবজেক্ট কিনা তা আপনি কীভাবে পরীক্ষা করেন? )

এটি Opera 11, ফায়ারফক্স 6, Internet Explorer 8 এবং গুগল ক্রোম 16 এ পরীক্ষা করা হয়েছিল।

কোড

function mergeRecursive() {

  // _mergeRecursive does the actual job with two arguments.
  var _mergeRecursive = function (dst, src) {
    if (isDOMNode(src) || typeof src !== 'object' || src === null) {
      return dst;
    }

    for (var p in src) {
      if (!src.hasOwnProperty(p))
        continue;
      if (src[p] === undefined)
        continue;
      if ( typeof src[p] !== 'object' || src[p] === null) {
        dst[p] = src[p];
      } else if (typeof dst[p]!=='object' || dst[p] === null) {
        dst[p] = _mergeRecursive(src[p].constructor===Array ? [] : {}, src[p]);
      } else {
        _mergeRecursive(dst[p], src[p]);
      }
    }
    return dst;
  }

  // Loop through arguments and merge them into the first argument.
  var out = arguments[0];
  if (typeof out !== 'object' || out === null)
    return out;
  for (var i = 1, il = arguments.length; i < il; i++) {
    _mergeRecursive(out, arguments[i]);
  }
  return out;
}

কিছু উদাহরণ

এইচটিএমএল এলিমেন্টের অভ্যন্তরীণ HTML এবং স্টাইল সেট করুন

mergeRecursive(
  document.getElementById('mydiv'),
  {style: {border: '5px solid green', color: 'red'}},
  {innerHTML: 'Hello world!'});

অ্যারে এবং বস্তু মার্জ করুন। উল্লেখ্য যে undefined lefthand অ্যারে / বস্তুর মান সংরক্ষণ করতে ব্যবহার করা যেতে পারে।

o = mergeRecursive({a:'a'}, [1,2,3], [undefined, null, [30,31]], {a:undefined, b:'b'});
// o = {0:1, 1:null, 2:[30,31], a:'a', b:'b'}

যেকোন যুক্তি একটি জাভাস্ক্রিপ্ট অবজেক্ট (নুল সহ) না করা উপেক্ষা করা হবে। প্রথম যুক্তি ব্যতীত, এছাড়াও DOM নোড বাতিল করা হয়। নতুন স্ট্রিং (যেমন স্ট্রিং) এর মতো স্ট্রিংগুলি সচেতন থাকুন।

o = mergeRecursive({a:'a'}, 1, true, null, undefined, [1,2,3], 'bc', new String('de'));
// o = {0:'d', 1:'e', 2:3, a:'a'}

যদি আপনি দুটি বস্তু এক নতুন (দুটিতে কোনও ক্ষতি না করে) মার্জ করতে চান {} প্রথম যুক্তি হিসাবে

var a={}, b={b:'abc'}, c={c:'cde'}, o;
o = mergeRecursive(a, b, c);
// o===a is true, o===b is false, o===c is false

সম্পাদনা (রিপারসুন দ্বারা):

অ্যারে মার্জ করতে

function mergeRecursive(obj1, obj2) {
  if (Array.isArray(obj2)) { return obj1.concat(obj2); }
  for (var p in obj2) {
    try {
      // Property in destination object set; update its value.
      if ( obj2[p].constructor==Object ) {
        obj1[p] = mergeRecursive(obj1[p], obj2[p]);
      } else if (Array.isArray(obj2[p])) {
        obj1[p] = obj1[p].concat(obj2[p]);
      } else {
        obj1[p] = obj2[p];
      }
    } catch(e) {
      // Property in destination object not set; create it and set its value.
      obj1[p] = obj2[p];
    }
  }
  return obj1;
}

Underscore.js দিয়ে বস্তুর একটি অ্যারে মার্জ করতে:

var arrayOfObjects = [ {a:1}, {b:2, c:3}, {d:4} ];
_(arrayOfObjects).reduce(function(memo, o) { return _(memo).extend(o); });

এতে ফলাফল:

Object {a: 1, b: 2, c: 3, d: 4}

আপনি লোডশ এর defaultsDeep ব্যবহার করা উচিতdefaultsDeep

_.defaultsDeep({ 'user': { 'name': 'barney' } }, { 'user': { 'name': 'fred', 'age': 36 } });
// → { 'user': { 'name': 'barney', 'age': 36 } }







javascript-objects