Javascript根据另一个对象的键和值编写新的对象

时间:2022-09-25 08:10:41

I have a large object, and not each element within the object has the same keys or number of keys. The first element has all the keys, and this first element's values are what I want to actually USE as the keys for each element, filling in with blanks where the element does not have this key.

我有一个大的对象,对象中的每个元素都没有相同的键或键数。第一个元素有所有的键,而第一个元素的值实际上是我想作为每个元素的键,在元素没有这个键的地方填充空格。

I can wrap my brain around WHAT needs to happen, but I just can't figure out how to code it. This is the sample as I import it:

我可以用脑子去思考需要发生什么,但我就是想不出如何去编码它。这是我进口的样品:

[
    {
        "A": "Name",
        "B": "Type",
        "C": "Company",
        "D": "Year",
        "E": "Alt1",
        "F": "Name1",
        "G": "Alt2",
        "H": "Name2",
        "I": "Notes"
    },
    {
        "A": "Skittles",
        "C": "Mars",
        "D": 0,
        "E": "Cadbury",
        "F": "Sour Patch Kids",
        "I": "CLEAN"
    },
    {
        "A": "Love",
        "B": "Chocolate",
        "C": "Dove",
        "D": 0,
        "E": "0",
        "F": "0",
    }
]

In this example, the second element is missing keys "B", "G", and "H", while the third element is missing keys "G", "H" and "I". So using the FIRST element's keys A through I as a master template, I want to rewrite a new object, that looks like this:

在本例中,第二个元素缺少键“B”、“G”和“H”,而第三个元素缺少键“G”、“H”和“I”。使用第一个元素的键A通过I作为主模板,我想重写一个新对象,它看起来是这样的:

[
    {
        "Name": "Skittles",
        "Type": "",
        "Company": "Mars",
        "Year": 0,
        "Alt1": "Cadbury",
        "Name1": "Sour Patch Kids",
        "Alt2": "",
        "Name2": "",
        "Notes": "CLEAN"
    },
    {
        "Name": "Love",
        "Type" : "Chocolate",
        "Company": "Dove",
        "Year": 0,
        "Alt1": "",
        "Name1": "",
        "Alt2": "",
        "Name2": "",
        "Notes": ""
    }
]

I've written several for loops but I cannot seem to grasp the complexity of this... This is as far as I've gotten:

我已经写了几个for循环,但是我似乎无法理解这个的复杂性……就我所知

a = [];
b = [];
new_keys = [];

/* Capture the new keys */
for(var v in user_file[0]) {
  if(user_file[0].hasOwnProperty(v)) {
    new_keys.push(user_file[0][v]);
  }
}

/* user_file is the object I pasted above... */
for ( var i = 0 ; i<user_file.length; i++ ) {
    /* write the b object */

    /* then push that object into a */
    a.push(b);

    /* Empty out b */
    b = [];
}

I have no idea how to write this b[] object....

我不知道如何写这个b[]对象....

5 个解决方案

#1


1  

You could iterate only the elements from index 1 and greater and take the object at index zero as blue print for the objects.

您可以只迭代索引1中的元素,并将索引0处的对象作为对象的蓝色打印。

var data = [{ A: "Name", B: "Type", C: "Company", D: "Year", E: "Alt1", F: "Name1", G: "Alt2", H: "Name2", I: "Notes" }, { A: "Skittles", C: "Mars", D: 0, E: "Cadbury", F: "Sour Patch Kids", I: "CLEAN" }, { A: "Love", B: "Chocolate", C: "Dove", D: 0, E: "0", F: "0", }],
    keys = Object.keys(data[0]),
    result = data.slice(1).map(function (o) {
        var temp = {};
        keys.forEach(function (k) {
            temp[data[0][k]] = k in o ? o[k] : '';
        });
        return temp;
    });

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

#2


2  

You're really close.

你真的很接近。

In Javascript, you can actually access objects like arrays. obj['key1'] will return the same value as obj.key1.

在Javascript中,您实际上可以访问数组之类的对象。obj['key1']将返回与object .key1相同的值。

Now that you have a list of those keys, and you know which letter, A, B, C, etc. corresponds to which key (user_file[0][letter]) you can actually iterate through these keys and use a temporary object to store the information (tmp[user_file[0][letter]] = user_file[i][letter]).

现在您已经有了这些键的列表,并且您知道了哪个字母a、B、C等对应于哪个键(user_file[0][letter]),您实际上可以遍历这些键并使用一个临时对象来存储信息(tmp[user_file[0][letter]]] = user_file[i][letter])。

But what if user_file[i][letter] doesn't exist? This is where one of the coolest features about javascript comes into play: truthiness. When an object doesn't have a property and you try to access it, it will return a falsy value (either null or undefined, I can't remember off the top of my head).

但是如果user_file[i][letter]不存在呢?这就是javascript最酷的特性之一:truthiness。当一个对象没有属性并试图访问它时,它将返回一个falsy值(null或undefined,我记不起)。

So how do you apply the truthiness? Well you can kinda treat it like a boolean (kinda) and actually use an || operation on it. This is a technique called coalescing.

那么如何运用真实感呢?你可以把它当作布尔值(有点)然后用||操作。这是一种叫做合并的技术。

tmp[user_file[0][letter]] = user_file[i][letter] || "";

To put this line in simple terms if user_file[i][letter] doesn't exist use "" instead.

如果user_file[i][letter]不存在,则使用“”来简单地表示这一行。

Awesome that's a cool line but what next? Well now we just have to put everything together.

太棒了,很酷,但是接下来呢?现在我们要把所有东西都放在一起。

If you place your first loop in a loop that iterates through the rest of the object array, we can do it all right there:

如果您将第一个循环放置在一个循环中,该循环遍历对象数组的其余部分,那么我们可以在此完成:

for(var i = 1; i < user_file.length; i++) {
    var tmp = {};
    for(var v in user_file[0]) {
      if(user_file[0].hasOwnProperty(v)) {
        tmp[user_file[0][v]] = user_file[i][v] || "";
      }
    }
   a.push(tmp);
}

And there you have it, an object array from values in objects later than the first element, using the first element's values as the keys, even if the later elements don't have values that correspond with those keys.

这里有一个对象数组,对象数组来自对象中比第一个元素晚的值,使用第一个元素的值作为键,即使后面的元素没有与这些键对应的值。

#3


1  

You can simplify the process by using Array methods like forEach and map in conjunction with Object.keys.

通过使用forEach等数组方法和结合Object.keys映射,可以简化过程。

var array = [
    {
        "A": "Name",
        "B": "Type",
        "C": "Company",
        "D": "Year",
        "E": "Alt1",
        "F": "Name1",
        "G": "Alt2",
        "H": "Name2",
        "I": "Notes"
    },
    {
        "A": "Skittles",
        "C": "Mars",
        "D": 0,
        "E": "Cadbury",
        "F": "Sour Patch Kids",
        "I": "CLEAN"
    },
    {
        "A": "Love",
        "B": "Chocolate",
        "C": "Dove",
        "D": 0,
        "E": "0",
        "F": "0",
    }
]

var master = array.shift()

master = Object.keys(master).map(function (k) { return [k, this[k]] }, master)

array.forEach(function (e) {
  master.forEach(function (pair) {
    var value = pair[0] in e ? e[pair[0]] : defaultValueFor(pair[0])
    delete e[pair[0]]
    e[pair[1]] = value
  })
})

console.log(array)


function defaultValueFor (key) {
  return key === 'Year' ? 0 : ''
}

#4


1  

Here's a step-by-step breakdown of one way of getting this done. This does have the advantage of not needing any ternary or if blocks...

以下是一种逐步分解的方法。这的确具有不需要任何三元或如果块…

var user_file = [
    {
        "A": "Name",
        "B": "Type",
        "C": "Company",
        "D": "Year",
        "E": "Alt1",
        "F": "Name1",
        "G": "Alt2",
        "H": "Name2",
        "I": "Notes"
    },
    {
        "A": "Skittles",
        "C": "Mars",
        "D": 0,
        "E": "Cadbury",
        "F": "Sour Patch Kids",
        "I": "CLEAN"
    },
    {
        "A": "Love",
        "B": "Chocolate",
        "C": "Dove",
        "D": 0,
        "E": "0",
        "F": "0",
    }
];
// split off the first set of keys
var keys = user_file[0];
// keep the data separate
var data = user_file.splice(1);
// iterate over the data
var result = data.map(function (item) {
   // item is now one of the last two items
   // get the keys for that item
   var itemKeys = Object.keys(item); 
   // Make a blank
   var newItem = {};
   // iterate over the keys
   itemKeys.forEach(function (key) {
      // get the "real" key name
      var realKey = keys[key]; 
      // set the value of that key to the value of the item
      newItem[realKey] = item[key];
   });
   // add to result
   return newItem;
});
console.log(result);

#5


1  

There is probably a more efficient way of doing this, but this is something I threw together that will work.

也许有一种更有效的方法可以做到这一点,但是我把这些东西放在一起就可以了。

var data = [{
  "A": "Name",
  "B": "Type",
  "C": "Company",
  "D": "Year",
  "E": "Alt1",
  "F": "Name1",
  "G": "Alt2",
  "H": "Name2",
  "I": "Notes"
}, {
  "A": "Skittles",
  "C": "Mars",
  "D": 0,
  "E": "Cadbury",
  "F": "Sour Patch Kids",
  "I": "CLEAN"
}, {
  "A": "Love",
  "B": "Chocolate",
  "C": "Dove",
  "D": 0,
  "E": "0",
  "F": "0",
}];

var keyMap = data.shift();
var templateObj = {
  "A": '',
  "B": '',
  "C": '',
  "D": '',
  "E": '',
  "F": '',
  "G": '',
  "H": '',
  "I": '',
};
var results = [];

data.forEach(function(item) {
  var tmpResult = Object.assign({}, templateObj, item);
  var processedItem = {};
  for (var prop in tmpResult) {
    processedItem[keyMap[prop]] = tmpResult[prop];
  }
  results.push(processedItem);
});

console.log(results);

#1


1  

You could iterate only the elements from index 1 and greater and take the object at index zero as blue print for the objects.

您可以只迭代索引1中的元素,并将索引0处的对象作为对象的蓝色打印。

var data = [{ A: "Name", B: "Type", C: "Company", D: "Year", E: "Alt1", F: "Name1", G: "Alt2", H: "Name2", I: "Notes" }, { A: "Skittles", C: "Mars", D: 0, E: "Cadbury", F: "Sour Patch Kids", I: "CLEAN" }, { A: "Love", B: "Chocolate", C: "Dove", D: 0, E: "0", F: "0", }],
    keys = Object.keys(data[0]),
    result = data.slice(1).map(function (o) {
        var temp = {};
        keys.forEach(function (k) {
            temp[data[0][k]] = k in o ? o[k] : '';
        });
        return temp;
    });

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

#2


2  

You're really close.

你真的很接近。

In Javascript, you can actually access objects like arrays. obj['key1'] will return the same value as obj.key1.

在Javascript中,您实际上可以访问数组之类的对象。obj['key1']将返回与object .key1相同的值。

Now that you have a list of those keys, and you know which letter, A, B, C, etc. corresponds to which key (user_file[0][letter]) you can actually iterate through these keys and use a temporary object to store the information (tmp[user_file[0][letter]] = user_file[i][letter]).

现在您已经有了这些键的列表,并且您知道了哪个字母a、B、C等对应于哪个键(user_file[0][letter]),您实际上可以遍历这些键并使用一个临时对象来存储信息(tmp[user_file[0][letter]]] = user_file[i][letter])。

But what if user_file[i][letter] doesn't exist? This is where one of the coolest features about javascript comes into play: truthiness. When an object doesn't have a property and you try to access it, it will return a falsy value (either null or undefined, I can't remember off the top of my head).

但是如果user_file[i][letter]不存在呢?这就是javascript最酷的特性之一:truthiness。当一个对象没有属性并试图访问它时,它将返回一个falsy值(null或undefined,我记不起)。

So how do you apply the truthiness? Well you can kinda treat it like a boolean (kinda) and actually use an || operation on it. This is a technique called coalescing.

那么如何运用真实感呢?你可以把它当作布尔值(有点)然后用||操作。这是一种叫做合并的技术。

tmp[user_file[0][letter]] = user_file[i][letter] || "";

To put this line in simple terms if user_file[i][letter] doesn't exist use "" instead.

如果user_file[i][letter]不存在,则使用“”来简单地表示这一行。

Awesome that's a cool line but what next? Well now we just have to put everything together.

太棒了,很酷,但是接下来呢?现在我们要把所有东西都放在一起。

If you place your first loop in a loop that iterates through the rest of the object array, we can do it all right there:

如果您将第一个循环放置在一个循环中,该循环遍历对象数组的其余部分,那么我们可以在此完成:

for(var i = 1; i < user_file.length; i++) {
    var tmp = {};
    for(var v in user_file[0]) {
      if(user_file[0].hasOwnProperty(v)) {
        tmp[user_file[0][v]] = user_file[i][v] || "";
      }
    }
   a.push(tmp);
}

And there you have it, an object array from values in objects later than the first element, using the first element's values as the keys, even if the later elements don't have values that correspond with those keys.

这里有一个对象数组,对象数组来自对象中比第一个元素晚的值,使用第一个元素的值作为键,即使后面的元素没有与这些键对应的值。

#3


1  

You can simplify the process by using Array methods like forEach and map in conjunction with Object.keys.

通过使用forEach等数组方法和结合Object.keys映射,可以简化过程。

var array = [
    {
        "A": "Name",
        "B": "Type",
        "C": "Company",
        "D": "Year",
        "E": "Alt1",
        "F": "Name1",
        "G": "Alt2",
        "H": "Name2",
        "I": "Notes"
    },
    {
        "A": "Skittles",
        "C": "Mars",
        "D": 0,
        "E": "Cadbury",
        "F": "Sour Patch Kids",
        "I": "CLEAN"
    },
    {
        "A": "Love",
        "B": "Chocolate",
        "C": "Dove",
        "D": 0,
        "E": "0",
        "F": "0",
    }
]

var master = array.shift()

master = Object.keys(master).map(function (k) { return [k, this[k]] }, master)

array.forEach(function (e) {
  master.forEach(function (pair) {
    var value = pair[0] in e ? e[pair[0]] : defaultValueFor(pair[0])
    delete e[pair[0]]
    e[pair[1]] = value
  })
})

console.log(array)


function defaultValueFor (key) {
  return key === 'Year' ? 0 : ''
}

#4


1  

Here's a step-by-step breakdown of one way of getting this done. This does have the advantage of not needing any ternary or if blocks...

以下是一种逐步分解的方法。这的确具有不需要任何三元或如果块…

var user_file = [
    {
        "A": "Name",
        "B": "Type",
        "C": "Company",
        "D": "Year",
        "E": "Alt1",
        "F": "Name1",
        "G": "Alt2",
        "H": "Name2",
        "I": "Notes"
    },
    {
        "A": "Skittles",
        "C": "Mars",
        "D": 0,
        "E": "Cadbury",
        "F": "Sour Patch Kids",
        "I": "CLEAN"
    },
    {
        "A": "Love",
        "B": "Chocolate",
        "C": "Dove",
        "D": 0,
        "E": "0",
        "F": "0",
    }
];
// split off the first set of keys
var keys = user_file[0];
// keep the data separate
var data = user_file.splice(1);
// iterate over the data
var result = data.map(function (item) {
   // item is now one of the last two items
   // get the keys for that item
   var itemKeys = Object.keys(item); 
   // Make a blank
   var newItem = {};
   // iterate over the keys
   itemKeys.forEach(function (key) {
      // get the "real" key name
      var realKey = keys[key]; 
      // set the value of that key to the value of the item
      newItem[realKey] = item[key];
   });
   // add to result
   return newItem;
});
console.log(result);

#5


1  

There is probably a more efficient way of doing this, but this is something I threw together that will work.

也许有一种更有效的方法可以做到这一点,但是我把这些东西放在一起就可以了。

var data = [{
  "A": "Name",
  "B": "Type",
  "C": "Company",
  "D": "Year",
  "E": "Alt1",
  "F": "Name1",
  "G": "Alt2",
  "H": "Name2",
  "I": "Notes"
}, {
  "A": "Skittles",
  "C": "Mars",
  "D": 0,
  "E": "Cadbury",
  "F": "Sour Patch Kids",
  "I": "CLEAN"
}, {
  "A": "Love",
  "B": "Chocolate",
  "C": "Dove",
  "D": 0,
  "E": "0",
  "F": "0",
}];

var keyMap = data.shift();
var templateObj = {
  "A": '',
  "B": '',
  "C": '',
  "D": '',
  "E": '',
  "F": '',
  "G": '',
  "H": '',
  "I": '',
};
var results = [];

data.forEach(function(item) {
  var tmpResult = Object.assign({}, templateObj, item);
  var processedItem = {};
  for (var prop in tmpResult) {
    processedItem[keyMap[prop]] = tmpResult[prop];
  }
  results.push(processedItem);
});

console.log(results);