库存更新问题
---恢复内容开始---
用对象确实比用数组解决起该问题来方便得多,我一开始也是想的用对象来做,但是不知道怎么把对象转换成数组,而且对于对象的排序简直一筹莫展。实际情况是,名值对的形式非常适合用对象来解决,因为对象就是用名值对来定义的。而排序又是数组的专利,所以这个问题一定是要同时用到两者,那就免不了要在两者中间转换。
首先看如何转换。数组转换成对象,用的是数组的forEach方法,然后一条语句object[name]=value就解决了。
1 function createObject(array) { 2 var obj = {}; // We start off by creating an empty object. 3 array.forEach(function(current) { // We loop over the input array. 4 obj[current[1]] = current[0]; // We add properties to the object for each item. E.g.: { 'Computer Screen' : 5 } 5 }); 6 return obj; // We return the object itself. 7 }
对象转换成数组也相当简单,用的是for...in语句,然后将每一项push到数组里去。
1 function createArray(object) { 2 var array = []; // We create an empty array. 3 for (var key in object) { // We loop over each key in the input object. 4 array.push([object[key], key]); // We push each object key name and value to the array. 5 } 6 return array; // Finally, we return the array. 7 }
存货问题的解决逻辑就是两句话:
遍历要添加的目录(为什么不是旧目录呢,因为要添加的目录里的每一项都会被处理而旧目录并非)
1.如果item在当前目录中存在,就把他们的值相加;
2.如果item在当前目录中不存在,就在目录中添加。
用forEach()方法遍历待添加目录的每一项,提取该项的名称用对象的hasOwnProperty()方法检查是否在原目录中存在,再分别处理。
排序与我而言是难点,我想到的是用charCodeAt()之类的方法,但其实就是我所熟知的数组sort()方法。
function compareFunction(a, b) { if (a < b) { return -1; // a goes before b } else if (a > b) { return 1; // b goes before a } else { return 0; // a and b are equal } }
对名称的首字母排序而非其他,代码如下:
1 return createArray(currentInventory).sort(function(a, b) { 2 if (a[1] < b[1]) return -1; // If the first item's name is lesser than the second's, we return -1 3 if (a[1] > b[1]) return 1; // In the opposite case, we return 1 4 return 0; // This case should not happen in this example, but if they were to be equal, we return 0. 5 });
最终代码如下:
1 function inventory(arr1, arr2) { 2 3 if (!Array.isArray(arr1)) { 4 return []; 5 }; 6 7 var currentInventory = createObject(arr1); 8 9 arr2.forEach(function(current) { 10 if (currentInventory.hasOwnProperty(current[1])) { 11 currentInventory[current[1]] += current[0]; 12 } else { 13 currentInventory[current[1]] = current[0]; 14 } 15 }); 16 17 // First, we create the array, we then apply sort. 18 return createArray(currentInventory).sort(function(a, b) { 19 if (a[1] < b[1]) return -1; // If the first item's name is lesser than the second's, we return -1 20 if (a[1] > b[1]) return 1; // In the opposite case, we return 1 21 return 0; // This case should not happen in this example, but if they were to be equal, we return 0. 22 }); 23 24 function createObject(array) { 25 var obj = {}; 26 array.forEach(function(current) { 27 obj[current[1]] = current[0]; 28 }); 29 return obj; 30 } 31 32 function createArray(object) { 33 var array = []; 34 for (var key in object) { 35 array.push([object[key], key]); 36 } 37 return array; 38 } 39 }
最后附上我个人的烂解法,值得赞扬的地方是基本逻辑是正确的,但没有想到对象和数组各自的优势,也不知道如何转换,排序部分更是没做。
1 function updateInventory(arr1, arr2) { 2 // All inventory must be accounted for or you're fired! 3 for(var i = 0; i<arr2.length;i++){ 4 var inventoryName = arr2[i][1]; 5 var inventoryNumber = getNumber(inventoryName,arr2); 6 if(isExist(inventoryName,arr1)){ 7 var location = getLocation(inventoryName,arr1); 8 arr1[location][0] += inventoryNumber; 9 }else{ 10 arr1.push([inventoryNumber,inventoryName]); 11 } 12 } 13 function getNumber(name,arr){ 14 for(var i = 0; i<arr.length;i++){ 15 if(arr[i][1] === name){ 16 return arr[i][0]; 17 } 18 } 19 } 20 function isExist(name,arr){ 21 for(var i = 0; i<arr.length;i++){ 22 if(arr[i][1] === name){ 23 return true; 24 } 25 } 26 } 27 function getLocation(name,arr){ 28 for(var i = 0; i<arr.length;i++){ 29 if(arr[i][1] === name){ 30 return i; 31 } 32 } 33 } 34 return arr1; 35 }
---恢复内容结束---