如何在JavaScript中执行这个映射?

huangapple go评论117阅读模式
英文:

How would you guys do this mapping in JavaScript?

问题

以下是您提供的代码的翻译部分:

  1. 让我们假设我有一个如下的数组
  2. [100,2,3,4,200,35,42,300,4,4,4,6,7,400,2]
  3. 我想创建一个映射如下所示
  4. {
  5. { key: 100,
  6. value: 2
  7. },
  8. { key: 100,
  9. value: 3
  10. }
  11. { key: 100,
  12. value: 4
  13. },
  14. { key: 200,
  15. value: 35
  16. },
  17. { key: 200,
  18. value: 42
  19. },
  20. { key: 300,
  21. value: 4
  22. },
  23. { key: 300,
  24. value: 4
  25. },
  26. { key: 300,
  27. value: 4
  28. },
  29. { key: 300,
  30. value: 6
  31. },
  32. { key: 300,
  33. value: 7
  34. },
  35. { key: 400,
  36. value: 2
  37. },
  38. }
  39. 较大数组中的所有值都是具有一个或多个字段的对象
  40. 我使用数字100200300400来模拟只使用一个字段的值其余的值当然包含多个字段
  41. 我的目标是使用当前的标志flag创建映射元素后面跟随的项目使用它对于标志flag300后续的元素是4,4,4,6,7
  42. 这是我尝试过的代码
  43. let flagAndFollowingValues = new Map();
  44. let j=0;
  45. let followingElementsArray = [];
  46. console.log(itemsToBeCheckedArray[j]);
  47. for(let i=0; i<bigArray.length; i++){
  48. if(Object.keys(bigArray[i]).length > 1)
  49. {
  50. followingElementsArray.push(bigArray[i]);
  51. }else if(Object.keys(bigArray[i]).length === 1){
  52. if(i===0){
  53. j++;
  54. flagAndFollowingValues.set(itemsToBeCheckedArray[j], followingElementsArray);
  55. followingElementsArray=[];
  56. }else{
  57. flagAndFollowingValues.set(itemsToBeCheckedArray[j], followingElementsArray);
  58. followingElementsArray=[];
  59. }
  60. }
  61. }

希望这对您有所帮助。

英文:

Let's say I have an array as follows:

  1. [100,2,3,4,200,35,42,300,4,4,4,6,7,400,2]

And I want to create a map, like so:

  1. {
  2. { key: 100,
  3. value: 2
  4. },
  5. { key: 100,
  6. value: 3
  7. }
  8. { key: 100,
  9. value: 4
  10. },
  11. { key: 200,
  12. value: 35
  13. },
  14. { key: 200,
  15. value: 42
  16. },
  17. { key: 300,
  18. value: 4
  19. },
  20. { key: 300,
  21. value: 4
  22. },
  23. { key: 300,
  24. value: 4
  25. },
  26. { key: 300,
  27. value: 6
  28. },
  29. { key: 300,
  30. value: 7
  31. },
  32. { key: 400,
  33. value: 2
  34. },
  35. }

All the values in the bigger array are objects which have one or more fields.

I simulated the values with only one field using numbers 100, 200, 300, 400. You can call them flags. The rest of them being values with more than 1 field, of course.

My goal is to create map elements using the current flag with the items that follow it. For flag 300, the following elements are 4,4,4,6,7.

Here is what I tried:

  1. let flagAndFollowingValues = new Map();
  2. let j=0;
  3. let followingElementsArray = [];
  4. console.log(itemsToBeCheckedArray[j]);
  5. for(let i=0; i&lt;bigArray.length; i++){
  6. if(Object.keys(bigArray[i]).length &gt; 1)
  7. {
  8. followingElementsArray.push(bigArray[i]);
  9. }else if(Object.keys(bigArray[i]).length === 1){
  10. if(i===0){
  11. j++;
  12. flagAndFollowingValues.set(itemsToBeCheckedArray[j], followingElementsArray);
  13. followingElementsArray=[];
  14. }else{
  15. flagAndFollowingValues.set(itemsToBeCheckedArray[j], followingElementsArray);
  16. followingElementsArray=[];
  17. }
  18. }
  19. }

答案1

得分: 3

另一个使用单个标志而不是if/else/map的reduce()选项

  1. 如果当前值大于100,将flag设置为该值。
  2. 否则,向数组中添加一个新对象,keyflagvalue为当前值。
  1. const data = [100,2,3,4,200,35,42,300,4,4,4,6,7,400,2];
  2. let flag = null;
  3. const result = data.reduce((p, c, i) => {
  4. if (c >= 100) {
  5. flag = c;
  6. } else {
  7. p.push({ key: flag, value: c });
  8. }
  9. return p;
  10. }, []);
  11. console.log(result);
英文:

Another reduce() option using a single flag instead of if/else/map's


  1. If the current value if larger then 100, set flag to that value
  2. Otherwise, add a new object to the array, with flag as key and the current value as the value.

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-js -->

  1. const data = [100,2,3,4,200,35,42,300,4,4,4,6,7,400,2];
  2. let flag = null;
  3. const result = data.reduce((p, c, i) =&gt; {
  4. if (c &gt;= 100) {
  5. flag = c;
  6. } else {
  7. p.push({ key: flag, value: c });
  8. }
  9. return p;
  10. }, []);
  11. console.log(result);

<!-- end snippet -->

答案2

得分: 1

你可以通过将新的分组添加到结果数组的末尾来减少数据。

  1. 减少数据
    1. 如果值是键,则将其添加到累加器的末尾
    2. 否则,将当前值推送到累加器中的最后一个组中
  2. 将每个值组映射为一个带有其键的子值数组
  1. const
  2. input = [100, 2, 3, 4, 200, 35, 42, 300, 4, 4, 4, 6, 7, 400, 2],
  3. processData = (arr, keyPredicate) => arr
  4. .reduce((acc, n) => {
  5. if (keyPredicate(n)) acc.push({ key: n, values: [] });
  6. else acc[acc.length - 1].values.push(n);
  7. return acc;
  8. }, [])
  9. .flatMap(({ key, values }) => values.map(value => ({ key, value }))),
  10. processed = processData(input, n => n >= 100);
  11. console.log(processed);
  1. .as-console-wrapper { top: 0; max-height: 100% !important; }
英文:

You can reduce the data by adding new groups to the end of the resulting array.

  1. Reduce the data
    1. If the value is a key, add it to the end of the accumulator
    2. Else, push the current value to the last group in the accumulator
  2. Flat-map each group of values into a sub-array of values (with their key)

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-js -->

  1. const
  2. input = [100, 2, 3, 4, 200, 35, 42, 300, 4, 4, 4, 6, 7, 400, 2],
  3. processData = (arr, keyPredicate) =&gt; arr
  4. .reduce((acc, n) =&gt; {
  5. if (keyPredicate(n)) acc.push({ key: n, values: [] });
  6. else acc[acc.length - 1].values.push(n);
  7. return acc;
  8. }, [])
  9. .flatMap(({ key, values }) =&gt; values.map(value =&gt; ({ key, value }))),
  10. processed = processData(input, n =&gt; n &gt;= 100);
  11. console.log(processed);

<!-- language: lang-css -->

  1. .as-console-wrapper { top: 0; max-height: 100% !important; }

<!-- end snippet -->

答案3

得分: 0

首先创建一个地图逻辑,然后过滤掉错误的条目:

  1. // 声明当前键是什么,以便在需要时保存
  2. let currentKey = 0;
  3. // 我们只想返回键和值
  4. // 但如果数字能被100整除就不返回
  5. let result = [100,2,3,4,200,35,42,300,4,4,4,6,7,400,2].map(
  6. number => {
  7. // 检查是键还是值
  8. if (number % 100 === 0){
  9. currentKey = number
  10. return false;
  11. }
  12. return {key: currentKey, value: number}
  13. }
  14. );
  15. // 删除错误的键
  16. result = result.filter(entry => entry !== false)
  17. console.log(result)
英文:

First create a map logic, then filter out false entries:

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-js -->

  1. // Declare what your current key is, so we can save it when needed
  2. let currentKey = 0;
  3. // We just want to return the key and value
  4. // But not if the number is divisable by 100
  5. let result = [100,2,3,4,200,35,42,300,4,4,4,6,7,400,2].map(
  6. number =&gt; {
  7. // Check if key or value
  8. if (number % 100 === 0){
  9. currentKey = number
  10. return false;
  11. }
  12. return {key: currentKey, value: number}
  13. }
  14. );
  15. // Remove false keys
  16. result = result.filter(entry =&gt; entry !== false)
  17. console.log(result)

<!-- end snippet -->

答案4

得分: 0

你提出的结构是无用的,你可能想要的是像这样的映射:

100 => [2, 3, 4]
200 => [35, 42]

等等

英文:

Your proposed structure is useless, what you probably want is a map like

  1. 100 =&gt; [ 2, 3, 4 ]
  2. 200 =&gt; [ 35, 42 ]

etc

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-js -->

  1. let a = [100,2,3,4,200,35,42,300,4,4,4,6,7,400,2]
  2. let m = new Map()
  3. let key = null
  4. for (let x of a)
  5. if (x % 100 === 0)
  6. key = x
  7. else if (m.has(key))
  8. m.get(key).push(x)
  9. else
  10. m.set(key, [x])
  11. console.log([...m])

<!-- end snippet -->

答案5

得分: 0

如果你的标志是100的倍数,那么它将起作用。

  1. let flagObj = {};
  2. const data = [100, 2, 3, 4, 200, 35, 42, 300, 4, 4, 4, 6, 7, 400, 2];
  3. const res = data.reduce((acc, val, index) => {
  4. let flag = val % 100;
  5. if (flag === 0) {
  6. flagObj[val] = val;
  7. } else {
  8. let allFlags = Object.keys(flagObj);
  9. if (allFlags[allFlags.length - 1]) {
  10. let key = allFlags[allFlags.length - 1]
  11. acc.push({
  12. key,
  13. value: val,
  14. });
  15. }
  16. }
  17. return acc;
  18. }, []);
  19. console.log('result>>>>>>', res);
英文:

If your flag is a multiple of 100, in that case it will work

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-js -->

  1. let flagObj = {};
  2. const data = [100,2,3,4,200,35,42,300,4,4,4,6,7,400,2];
  3. const res = data.reduce((acc, val, index)=&gt; {
  4. let flag = val % 100;
  5. if(flag === 0 ){
  6. flagObj[val] = val;
  7. } else{
  8. let allFlags = Object.keys(flagObj);
  9. if(allFlags[allFlags.length-1]){
  10. let key = allFlags[allFlags.length -1]
  11. acc.push({
  12. key,
  13. value: val,
  14. });
  15. }
  16. }
  17. return acc;
  18. },[]);
  19. console.log(&#39;result&gt;&gt;&gt;&gt;&gt;&#39;, res);

<!-- end snippet -->

答案6

得分: 0

以下是您要翻译的内容:

如果我们有一个splitWhenever函数,它根据谓词的结果将数组拆分成连续值的子数组,我们可以简单地编写如下代码:

  1. const process = (xs) =>
  2. splitWhenever (n => n % 100 == 0) (xs)
  3. .flatMap (([key, ...vals]) => vals .map (value => ({key, value})))

这样的splitWhenever函数相当通用,在其他情况下也很有用,可以放入我们的个人工具包以在需要时重用。我们可以像这样使用它:

  1. const isOdd = (n => n % 2 === 1)
  2. splitWhenever (isOdd) ([5, 6, 8, 12, 3, 8, 10, 17, 24, 5, 7, 14, 28])
  3. //=> [[5, 6, 8, 12], [3, 8, 10], [17, 24], [5], [7, 14, 28]]

或者我们可以扩展它,以允许谓词检查当前值与前一个值是否相同,就像这样:

  1. const sameDecade = (x, y) => Math .floor (x / 10) !== Math .floor (y / 10)
  2. splitWhenever (sameDecade) ([23, 27, 22, 45, 42, 57, 51, 12, 16, 25, 27, 21])
  3. //=> [[23, 27, 22], [45, 42], [57, 51], [12, 16], [25, 27, 21]]

当然,这样的函数可以像这样使用:

  1. // const isFlag = (n) => n > 99)
  2. // const isFlag = (n) => [100, 200, 300, 400, 500, 1000] .includes (n)
  3. const isFlag = (n) => n % 100 == 0
  4. splitWhenever (isFlag) ([100, 2, 3, 4, 200, 35, 42, 300, 4, 4, 4, 6, 7, 400, 2])
  5. //=> [[100, 2, 3, 4], [200, 35, 42], [300, 4, 4, 4, 6, 7], [400, 2]]

(请注意isFlag的各种版本。问题并没有清楚地说明如何确定标志值。)

我有一个相当经常使用的splitWhenever函数。我们可以像这样使用它:

英文:

If we had a splitWhenever function that split an array into subarrays of consecutive values based on the result of a predicate, we could write this simply as

  1. const process = (xs) =&gt;
  2. splitWhenever (n =&gt; n % 100 == 0) (xs)
  3. .flatMap (([key, ...vals]) =&gt; vals .map (value =&gt; ({key, value})))

Such a splitWhenever is fairly generic and useful in other situations, and it might go in our personal toolkit to be reused as necessary. We might use it like this:

  1. const isOdd = (n =&gt; n % 2 === 1)
  2. splitWhenever (isOdd) ([5, 6, 8, 12, 3, 8, 10, 17, 24, 5, 7, 14, 28])
  3. //=&gt; [[5, 6, 8, 12], [3, 8, 10], [17, 24], [5], [7, 14, 28]]

Or we might extend it to allow the predicate to check the current value against the previous one, like this:

  1. const sameDecade = (x, y) =&gt; Math .floor (x / 10) !== Math .floor (y / 10)
  2. splitWhenever (sameDecade) ([23, 27, 22, 45, 42, 57, 51, 12, 16, 25, 27, 21])
  3. //=&gt; [[23, 27, 22], [45, 42], [57, 51], [12, 16], [25, 27, 21]]

And of course such a function could be used like this:

  1. // const isFlag = (n) =&gt; n &gt; 99)
  2. // const isFlag = (n) =&gt; [100, 200, 300, 400, 500, 1000] .includes (n)
  3. const isFlag = (n) =&gt; n % 100 == 0
  4. splitWhenever (isFlag) ([100, 2, 3, 4, 200, 35, 42, 300, 4, 4, 4, 6, 7, 400, 2])
  5. //=&gt; [[100, 2, 3, 4], [200, 35, 42], [300, 4, 4, 4, 6, 7], [400, 2]]

(Note the various versions of isFlag. The question doesn't make it clear how you determine the flag values.)

I have such a splitWhenever I used fairly often. We can use it like this:

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-js -->

  1. const splitWhenever = (pred) =&gt; (xs) =&gt;
  2. xs .length == 0 ? [] : xs .slice (1) .reduce (
  3. ((xss, x, i) =&gt; pred (x, xs[i])
  4. ? [...xss, [x]]
  5. : [...xss .slice (0, -1), [... xss [xss .length - 1], x]]
  6. ), [[xs [0]]]
  7. )
  8. const process = (xs) =&gt;
  9. splitWhenever (n =&gt; n % 100 == 0) (xs)
  10. .flatMap (([key, ...vals]) =&gt; vals .map (value =&gt; ({key, value})))
  11. console .log (
  12. process ([100, 2, 3, 4, 200, 35, 42, 300, 4, 4, 4, 6, 7, 400, 2])
  13. )

<!-- language: lang-css -->

  1. .as-console-wrapper {max-height: 100% !important; top: 0}

<!-- end snippet -->

答案7

得分: 0

You can use Array#forEachArray#push 方法如下所示:

  1. const input = [100, 2, 3, 4, 200, 35, 42, 300, 4, 4, 4, 6, 7, 400, 2],
  2. output = [];
  3. let key = 0;
  4. input.forEach(value => {
  5. if (value < 100) {
  6. output.push({ key, value });
  7. } else {
  8. key = value;
  9. }
  10. });
  11. console.log(output);
英文:

You can use Array#forEach and Array#push methods as follows:

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-js -->

  1. const
  2. input = [100,2,3,4,200,35,42,300,4,4,4,6,7,400,2],
  3. output = [];
  4. let
  5. key = 0;
  6. input.forEach(value =&gt; {
  7. if( value &lt; 100 ) {
  8. output.push({key, value});
  9. } else {
  10. key = value;
  11. }
  12. });
  13. console.log( output );

<!-- end snippet -->

答案8

得分: -1

我猜这段代码是不言自明的。只需迭代数组,要么获取一个新键,要么将值添加到当前键。

  1. const source = [100,2,3,4,200,35,42,300,4,4,4,6,7,400,2];
  2. const mapped = [];
  3. let key;
  4. for(const value of source){
  5. if(value % 100 === 0){
  6. key = value;
  7. continue;
  8. }
  9. mapped.push({key,value});
  10. }
  11. console.log(mapped);
英文:

I guess the code is self-explanatory. Just iterate the array and either get a new key or add a value to the current key.

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-js -->

  1. const source = [100,2,3,4,200,35,42,300,4,4,4,6,7,400,2];
  2. const mapped = [];
  3. let key;
  4. for(const value of source){
  5. if(value % 100 === 0){
  6. key = value;
  7. continue;
  8. }
  9. mapped.push({key,value});
  10. }
  11. console.log(mapped);

<!-- end snippet -->

huangapple
  • 本文由 发表于 2023年5月22日 20:03:45
  • 转载请务必保留本文链接:https://go.coder-hub.com/76306004.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定